diff options
Diffstat (limited to 'third_party/glog/src')
57 files changed, 0 insertions, 18285 deletions
diff --git a/third_party/glog/src/base/commandlineflags.h b/third_party/glog/src/base/commandlineflags.h deleted file mode 100644 index c8d50890269a..000000000000 --- a/third_party/glog/src/base/commandlineflags.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// This file is a compatibility layer that defines Google's version of -// command line flags that are used for configuration. -// -// We put flags into their own namespace. It is purposefully -// named in an opaque way that people should have trouble typing -// directly. The idea is that DEFINE puts the flag in the weird -// namespace, and DECLARE imports the flag from there into the -// current namespace. The net result is to force people to use -// DECLARE to get access to a flag, rather than saying -// extern bool FLAGS_logtostderr; -// or some such instead. We want this so we can put extra -// functionality (like sanity-checking) in DECLARE if we want, -// and make sure it is picked up everywhere. -// -// We also put the type of the variable in the namespace, so that -// people can't DECLARE_int32 something that they DEFINE_bool'd -// elsewhere. -#ifndef BASE_COMMANDLINEFLAGS_H__ -#define BASE_COMMANDLINEFLAGS_H__ - -#include "config.h" -#include <string> -#include <string.h> // for memchr -#include <stdlib.h> // for getenv - -#ifdef HAVE_LIB_GFLAGS - -#include <gflags/gflags.h> - -#else - -#include "glog/logging.h" - -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name -#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \ - namespace fL##shorttype { \ - GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ - char FLAGS_no##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) -#define DEFINE_bool(name, value, meaning) \ - DEFINE_VARIABLE(bool, B, name, value, meaning, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32) -#define DEFINE_int32(name, value, meaning) \ - DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32) - -// 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 GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#define DEFINE_string(name, value, meaning) \ - namespace fLS { \ - std::string FLAGS_##name##_buf(value); \ - GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name = FLAGS_##name##_buf; \ - char FLAGS_no##name; \ - } \ - using fLS::FLAGS_##name - -#endif // HAVE_LIB_GFLAGS - -// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we -// have GLOG_* environ variables even if we have gflags installed. -// -// If both an environment variable and a flag are specified, the value -// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the -// verbosity will be 1, not 0. - -#define GLOG_DEFINE_bool(name, value, meaning) \ - DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning) - -#define GLOG_DEFINE_int32(name, value, meaning) \ - DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning) - -#define GLOG_DEFINE_string(name, value, meaning) \ - DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning) - -// These macros (could be functions, but I don't want to bother with a .cc -// file), make it easier to initialize flags from the environment. - -#define EnvToString(envname, dflt) \ - (!getenv(envname) ? (dflt) : getenv(envname)) - -#define EnvToBool(envname, dflt) \ - (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL) - -#define EnvToInt(envname, dflt) \ - (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10)) - -#endif // BASE_COMMANDLINEFLAGS_H__ diff --git a/third_party/glog/src/base/googleinit.h b/third_party/glog/src/base/googleinit.h deleted file mode 100644 index 5a8b515cd604..000000000000 --- a/third_party/glog/src/base/googleinit.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Jacob Hoffman-Andrews - -#ifndef _GOOGLEINIT_H -#define _GOOGLEINIT_H - -class GoogleInitializer { - public: - typedef void (*void_function)(void); - GoogleInitializer(const char*, void_function f) { - f(); - } -}; - -#define REGISTER_MODULE_INITIALIZER(name, body) \ - namespace { \ - static void google_init_module_##name () { body; } \ - GoogleInitializer google_initializer_module_##name(#name, \ - google_init_module_##name); \ - } - -#endif /* _GOOGLEINIT_H */ diff --git a/third_party/glog/src/base/mutex.h b/third_party/glog/src/base/mutex.h deleted file mode 100644 index ced2b9950edc..000000000000 --- a/third_party/glog/src/base/mutex.h +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// --- -// Author: Craig Silverstein. -// -// A simple mutex wrapper, supporting locks and read-write locks. -// You should assume the locks are *not* re-entrant. -// -// To use: you should define the following macros in your configure.ac: -// ACX_PTHREAD -// AC_RWLOCK -// The latter is defined in ../autoconf. -// -// This class is meant to be internal-only and should be wrapped by an -// internal namespace. Before you use this module, please give the -// name of your internal namespace for this module. Or, if you want -// to expose it, you'll want to move it to the Google namespace. We -// cannot put this class in global namespace because there can be some -// problems when we have multiple versions of Mutex in each shared object. -// -// NOTE: by default, we have #ifdef'ed out the TryLock() method. -// This is for two reasons: -// 1) TryLock() under Windows is a bit annoying (it requires a -// #define to be defined very early). -// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG -// mode. -// If you need TryLock(), and either these two caveats are not a -// problem for you, or you're willing to work around them, then -// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs -// in the code below. -// -// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: -// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html -// Because of that, we might as well use windows locks for -// cygwin. They seem to be more reliable than the cygwin pthreads layer. -// -// TRICKY IMPLEMENTATION NOTE: -// This class is designed to be safe to use during -// dynamic-initialization -- that is, by global constructors that are -// run before main() starts. The issue in this case is that -// dynamic-initialization happens in an unpredictable order, and it -// could be that someone else's dynamic initializer could call a -// function that tries to acquire this mutex -- but that all happens -// before this mutex's constructor has run. (This can happen even if -// the mutex and the function that uses the mutex are in the same .cc -// file.) Basically, because Mutex does non-trivial work in its -// constructor, it's not, in the naive implementation, safe to use -// before dynamic initialization has run on it. -// -// The solution used here is to pair the actual mutex primitive with a -// bool that is set to true when the mutex is dynamically initialized. -// (Before that it's false.) Then we modify all mutex routines to -// look at the bool, and not try to lock/unlock until the bool makes -// it to true (which happens after the Mutex constructor has run.) -// -// This works because before main() starts -- particularly, during -// dynamic initialization -- there are no threads, so a) it's ok that -// the mutex operations are a no-op, since we don't need locking then -// anyway; and b) we can be quite confident our bool won't change -// state between a call to Lock() and a call to Unlock() (that would -// require a global constructor in one translation unit to call Lock() -// and another global constructor in another translation unit to call -// Unlock() later, which is pretty perverse). -// -// That said, it's tricky, and can conceivably fail; it's safest to -// avoid trying to acquire a mutex in a global constructor, if you -// can. One way it can fail is that a really smart compiler might -// initialize the bool to true at static-initialization time (too -// early) rather than at dynamic-initialization time. To discourage -// that, we set is_safe_ to true in code (not the constructor -// colon-initializer) and set it to true via a function that always -// evaluates to true, but that the compiler can't know always -// evaluates to true. This should be good enough. - -#ifndef GOOGLE_MUTEX_H_ -#define GOOGLE_MUTEX_H_ - -#include "config.h" // to figure out pthreads support - -#if defined(NO_THREADS) - typedef int MutexType; // to keep a lock-count -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN // We only need minimal includes -# endif -# ifdef GMUTEX_TRYLOCK - // We need Windows NT or later for TryEnterCriticalSection(). If you - // don't need that functionality, you can remove these _WIN32_WINNT - // lines, and change TryLock() to assert(0) or something. -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif -# endif -// To avoid macro definition of ERROR. -# ifndef NOGDI -# define NOGDI -# endif -// To avoid macro definition of min/max. -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include <windows.h> - typedef CRITICAL_SECTION MutexType; -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - // Needed for pthread_rwlock_*. If it causes problems, you could take it - // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it - // *does* cause problems for FreeBSD, or MacOSX, but isn't needed - // for locking there.) -# ifdef __linux__ -# ifndef _XOPEN_SOURCE // Some other header might have already set it for us. -# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls -# endif -# endif -# include <pthread.h> - typedef pthread_rwlock_t MutexType; -#elif defined(HAVE_PTHREAD) -# include <pthread.h> - typedef pthread_mutex_t MutexType; -#else -# error Need to implement mutex.h for your architecture, or #define NO_THREADS -#endif - -// We need to include these header files after defining _XOPEN_SOURCE -// as they may define the _XOPEN_SOURCE macro. -#include <assert.h> -#include <stdlib.h> // for abort() - -#define MUTEX_NAMESPACE glog_internal_namespace_ - -namespace MUTEX_NAMESPACE { - -class Mutex { - public: - // Create a Mutex that is not held by anybody. This constructor is - // typically used for Mutexes allocated on the heap or the stack. - // See below for a recommendation for constructing global Mutex - // objects. - inline Mutex(); - - // Destructor - inline ~Mutex(); - - inline void Lock(); // Block if needed until free then acquire exclusively - inline void Unlock(); // Release a lock acquired via Lock() -#ifdef GMUTEX_TRYLOCK - inline bool TryLock(); // If free, Lock() and return true, else return false -#endif - // Note that on systems that don't support read-write locks, these may - // be implemented as synonyms to Lock() and Unlock(). So you can use - // these for efficiency, but don't use them anyplace where being able - // to do shared reads is necessary to avoid deadlock. - inline void ReaderLock(); // Block until free or shared then acquire a share - inline void ReaderUnlock(); // Release a read share of this Mutex - inline void WriterLock() { Lock(); } // Acquire an exclusive lock - inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() - - // TODO(hamaji): Do nothing, implement correctly. - inline void AssertHeld() {} - - private: - MutexType mutex_; - // We want to make sure that the compiler sets is_safe_ to true only - // when we tell it to, and never makes assumptions is_safe_ is - // always true. volatile is the most reliable way to do that. - volatile bool is_safe_; - - inline void SetIsSafe() { is_safe_ = true; } - - // Catch the error of writing Mutex when intending MutexLock. - Mutex(Mutex* /*ignored*/) {} - // Disallow "evil" constructors - Mutex(const Mutex&); - void operator=(const Mutex&); -}; - -// Now the implementation of Mutex for various systems -#if defined(NO_THREADS) - -// When we don't have threads, we can be either reading or writing, -// but not both. We can have lots of readers at once (in no-threads -// mode, that's most likely to happen in recursive function calls), -// but only one writer. We represent this by having mutex_ be -1 when -// writing and a number > 0 when reading (and 0 when no lock is held). -// -// In debug mode, we assert these invariants, while in non-debug mode -// we do nothing, for efficiency. That's why everything is in an -// assert. - -Mutex::Mutex() : mutex_(0) { } -Mutex::~Mutex() { assert(mutex_ == 0); } -void Mutex::Lock() { assert(--mutex_ == -1); } -void Mutex::Unlock() { assert(mutex_++ == -1); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } -#endif -void Mutex::ReaderLock() { assert(++mutex_ > 0); } -void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } - -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) - -Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); } -Mutex::~Mutex() { DeleteCriticalSection(&mutex_); } -void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } -void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - TryEnterCriticalSection(&mutex_) != 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks -void Mutex::ReaderUnlock() { Unlock(); } - -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_rwlock_trywrlock(&mutex_) == 0 : - true; } -#endif -void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } -void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#undef SAFE_PTHREAD - -#elif defined(HAVE_PTHREAD) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_mutex_trylock(&mutex_) == 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } -void Mutex::ReaderUnlock() { Unlock(); } -#undef SAFE_PTHREAD - -#endif - -// -------------------------------------------------------------------------- -// Some helper classes - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } - ~MutexLock() { mu_->Unlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - MutexLock(const MutexLock&); - void operator=(const MutexLock&); -}; - -// ReaderMutexLock and WriterMutexLock do the same, for rwlocks -class ReaderMutexLock { - public: - explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } - ~ReaderMutexLock() { mu_->ReaderUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - ReaderMutexLock(const ReaderMutexLock&); - void operator=(const ReaderMutexLock&); -}; - -class WriterMutexLock { - public: - explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } - ~WriterMutexLock() { mu_->WriterUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - WriterMutexLock(const WriterMutexLock&); - void operator=(const WriterMutexLock&); -}; - -// Catch bug where variable name is omitted, e.g. MutexLock (&mu); -#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) -#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) -#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) - -} // namespace MUTEX_NAMESPACE - -using namespace MUTEX_NAMESPACE; - -#undef MUTEX_NAMESPACE - -#endif /* #define GOOGLE_MUTEX_H__ */ diff --git a/third_party/glog/src/config.h.cmake.in b/third_party/glog/src/config.h.cmake.in deleted file mode 100644 index 20f099050ee5..000000000000 --- a/third_party/glog/src/config.h.cmake.in +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef GLOG_CONFIG_H -#define GLOG_CONFIG_H - -/* define if glog doesn't use RTTI */ -#cmakedefine DISABLE_RTTI - -/* Namespace for Google classes */ -#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE} - -/* Define if you have the `dladdr' function */ -#cmakedefine HAVE_DLADDR - -/* Define if you have the `snprintf' function */ -#cmakedefine HAVE_SNPRINTF - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#cmakedefine HAVE_DLFCN_H - -/* Define to 1 if you have the <execinfo.h> header file. */ -#cmakedefine HAVE_EXECINFO_H - -/* Define if you have the `fcntl' function */ -#cmakedefine HAVE_FCNTL - -/* Define to 1 if you have the <glob.h> header file. */ -#cmakedefine HAVE_GLOB_H - -/* Define to 1 if you have the <inttypes.h> header file. */ -#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#cmakedefine HAVE_LIBPTHREAD - -/* Define to 1 if you have the <libunwind.h> header file. */ -#cmakedefine HAVE_LIBUNWIND_H - -/* define if you have google gflags library */ -#cmakedefine HAVE_LIB_GFLAGS - -/* define if you have google gmock library */ -#cmakedefine HAVE_LIB_GMOCK - -/* define if you have google gtest library */ -#cmakedefine HAVE_LIB_GTEST - -/* define if you have libunwind */ -#cmakedefine HAVE_LIB_UNWIND - -/* Define to 1 if you have the <memory.h> header file. */ -#cmakedefine HAVE_MEMORY_H - -/* define to disable multithreading support. */ -#cmakedefine NO_THREADS - -/* define if the compiler implements namespaces */ -#cmakedefine HAVE_NAMESPACES - -/* Define if you have the 'pread' function */ -#cmakedefine HAVE_PREAD - -/* Define if you have POSIX threads libraries and header files. */ -#cmakedefine HAVE_PTHREAD - -/* Define to 1 if you have the <pwd.h> header file. */ -#cmakedefine HAVE_PWD_H - -/* Define if you have the 'pwrite' function */ -#cmakedefine HAVE_PWRITE - -/* define if the compiler implements pthread_rwlock_* */ -#cmakedefine HAVE_RWLOCK - -/* Define if you have the 'sigaction' function */ -#cmakedefine HAVE_SIGACTION - -/* Define if you have the `sigaltstack' function */ -#cmakedefine HAVE_SIGALTSTACK - -/* Define to 1 if you have the <stdint.h> header file. */ -#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} - -/* Define to 1 if you have the <stdlib.h> header file. */ -#cmakedefine HAVE_STDLIB_H - -/* Define to 1 if you have the <strings.h> header file. */ -#cmakedefine HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#cmakedefine HAVE_STRING_H - -/* Define to 1 if you have the <syscall.h> header file. */ -#cmakedefine HAVE_SYSCALL_H - -/* Define to 1 if you have the <syslog.h> header file. */ -#cmakedefine HAVE_SYSLOG_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#cmakedefine HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/syscall.h> header file. */ -#cmakedefine HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the <sys/time.h> header file. */ -#cmakedefine HAVE_SYS_TIME_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} - -/* Define to 1 if you have the <sys/ucontext.h> header file. */ -#cmakedefine HAVE_SYS_UCONTEXT_H - -/* Define to 1 if you have the <sys/utsname.h> header file. */ -#cmakedefine HAVE_SYS_UTSNAME_H - -/* Define to 1 if you have the <sys/wait.h> header file. */ -#cmakedefine HAVE_SYS_WAIT_H - -/* Define to 1 if you have the <ucontext.h> header file. */ -#cmakedefine HAVE_UCONTEXT_H - -/* Define to 1 if you have the <unistd.h> header file. */ -#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} - -/* Define to 1 if you have the <unwind.h> header file. */ -#cmakedefine HAVE_UNWIND_H ${HAVE_UNWIND_H} - -/* define if the compiler supports using expression for operator */ -#cmakedefine HAVE_USING_OPERATOR - -/* define if your compiler has __attribute__ */ -#cmakedefine HAVE___ATTRIBUTE__ - -/* define if your compiler has __builtin_expect */ -#cmakedefine HAVE___BUILTIN_EXPECT ${HAVE___BUILTIN_EXPECT} - -/* define if your compiler has __sync_val_compare_and_swap */ -#cmakedefine HAVE___SYNC_VAL_COMPARE_AND_SWAP - -/* define if symbolize support is available */ -#cmakedefine HAVE_SYMBOLIZE - -/* define if localtime_r is available in time.h */ -#cmakedefine HAVE_LOCALTIME_R - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#cmakedefine LT_OBJDIR - -/* Name of package */ -#cmakedefine PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#cmakedefine PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#cmakedefine PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#cmakedefine PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#cmakedefine PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#cmakedefine PACKAGE_URL - -/* Define to the version of this package. */ -#cmakedefine PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#cmakedefine PC_FROM_UCONTEXT - -/* define if we should print file offsets in traces instead of symbolizing. */ -#cmakedefine PRINT_UNSYMBOLIZED_STACK_TRACES - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#cmakedefine PTHREAD_CREATE_JOINABLE - -/* The size of `void *', as computed by sizeof. */ -#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P} - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#cmakedefine STL_NAMESPACE ${STL_NAMESPACE} - -/* location of source code */ -#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR} - -/* Define to necessary thread-local storage attribute. */ -#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE} - -/* Check whether aligned_storage and alignof present */ -#cmakedefine HAVE_ALIGNED_STORAGE ${HAVE_ALIGNED_STORAGE} - -/* Version number of package */ -#cmakedefine VERSION - -#ifdef GLOG_BAZEL_BUILD - -/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved: - * https://github.com/bazelbuild/bazel/issues/3979 */ -#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE { - -#define _END_GOOGLE_NAMESPACE_ } - -#else - -/* Stops putting the code inside the Google namespace */ -#cmakedefine _END_GOOGLE_NAMESPACE_ ${_END_GOOGLE_NAMESPACE_} - -/* Puts following code inside the Google namespace */ -#cmakedefine _START_GOOGLE_NAMESPACE_ ${_START_GOOGLE_NAMESPACE_} - -#endif - -#endif // GLOG_CONFIG_H diff --git a/third_party/glog/src/config_for_unittests.h b/third_party/glog/src/config_for_unittests.h deleted file mode 100644 index 13ea8eab7a39..000000000000 --- a/third_party/glog/src/config_for_unittests.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// All Rights Reserved. -// -// Author: Craig Silverstein -// Copied from google-perftools and modified by Shinichiro Hamaji -// -// This file is needed for windows -- unittests are not part of the -// glog dll, but still want to include config.h just like the -// dll does, so they can use internal tools and APIs for testing. -// -// The problem is that config.h declares GOOGLE_GLOG_DLL_DECL to be -// for exporting symbols, but the unittest needs to *import* symbols -// (since it's not the dll). -// -// The solution is to have this file, which is just like config.h but -// sets GOOGLE_GLOG_DLL_DECL to do a dllimport instead of a dllexport. -// -// The reason we need this extra GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS -// variable is in case people want to set GOOGLE_GLOG_DLL_DECL explicitly -// to something other than __declspec(dllexport). In that case, they -// may want to use something other than __declspec(dllimport) for the -// unittest case. For that, we allow folks to define both -// GOOGLE_GLOG_DLL_DECL and GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS explicitly. -// -// NOTE: This file is equivalent to config.h on non-windows systems, -// which never defined GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS and always -// define GOOGLE_GLOG_DLL_DECL to the empty string. - -#include "config.h" - -#undef GOOGLE_GLOG_DLL_DECL -#ifdef GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS -# define GOOGLE_GLOG_DLL_DECL GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS -#else -// if DLL_DECL_FOR_UNITTESTS isn't defined, use "" -# define GOOGLE_GLOG_DLL_DECL -#endif diff --git a/third_party/glog/src/demangle.cc b/third_party/glog/src/demangle.cc deleted file mode 100644 index 9369f9a65c2d..000000000000 --- a/third_party/glog/src/demangle.cc +++ /dev/null @@ -1,1356 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// For reference check out: -// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling -// -// Note that we only have partial C++0x support yet. - -#include <stdio.h> // for NULL -#include "utilities.h" -#include "demangle.h" - -#if defined(OS_WINDOWS) -#include <dbghelp.h> -#pragma comment(lib, "dbghelp") -#endif - -_START_GOOGLE_NAMESPACE_ - -#if !defined(OS_WINDOWS) -typedef struct { - const char *abbrev; - const char *real_name; -} AbbrevPair; - -// List of operators from Itanium C++ ABI. -static const AbbrevPair kOperatorList[] = { - { "nw", "new" }, - { "na", "new[]" }, - { "dl", "delete" }, - { "da", "delete[]" }, - { "ps", "+" }, - { "ng", "-" }, - { "ad", "&" }, - { "de", "*" }, - { "co", "~" }, - { "pl", "+" }, - { "mi", "-" }, - { "ml", "*" }, - { "dv", "/" }, - { "rm", "%" }, - { "an", "&" }, - { "or", "|" }, - { "eo", "^" }, - { "aS", "=" }, - { "pL", "+=" }, - { "mI", "-=" }, - { "mL", "*=" }, - { "dV", "/=" }, - { "rM", "%=" }, - { "aN", "&=" }, - { "oR", "|=" }, - { "eO", "^=" }, - { "ls", "<<" }, - { "rs", ">>" }, - { "lS", "<<=" }, - { "rS", ">>=" }, - { "eq", "==" }, - { "ne", "!=" }, - { "lt", "<" }, - { "gt", ">" }, - { "le", "<=" }, - { "ge", ">=" }, - { "nt", "!" }, - { "aa", "&&" }, - { "oo", "||" }, - { "pp", "++" }, - { "mm", "--" }, - { "cm", "," }, - { "pm", "->*" }, - { "pt", "->" }, - { "cl", "()" }, - { "ix", "[]" }, - { "qu", "?" }, - { "st", "sizeof" }, - { "sz", "sizeof" }, - { NULL, NULL }, -}; - -// List of builtin types from Itanium C++ ABI. -static const AbbrevPair kBuiltinTypeList[] = { - { "v", "void" }, - { "w", "wchar_t" }, - { "b", "bool" }, - { "c", "char" }, - { "a", "signed char" }, - { "h", "unsigned char" }, - { "s", "short" }, - { "t", "unsigned short" }, - { "i", "int" }, - { "j", "unsigned int" }, - { "l", "long" }, - { "m", "unsigned long" }, - { "x", "long long" }, - { "y", "unsigned long long" }, - { "n", "__int128" }, - { "o", "unsigned __int128" }, - { "f", "float" }, - { "d", "double" }, - { "e", "long double" }, - { "g", "__float128" }, - { "z", "ellipsis" }, - { NULL, NULL } -}; - -// List of substitutions Itanium C++ ABI. -static const AbbrevPair kSubstitutionList[] = { - { "St", "" }, - { "Sa", "allocator" }, - { "Sb", "basic_string" }, - // std::basic_string<char, std::char_traits<char>,std::allocator<char> > - { "Ss", "string"}, - // std::basic_istream<char, std::char_traits<char> > - { "Si", "istream" }, - // std::basic_ostream<char, std::char_traits<char> > - { "So", "ostream" }, - // std::basic_iostream<char, std::char_traits<char> > - { "Sd", "iostream" }, - { NULL, NULL } -}; - -// State needed for demangling. -typedef struct { - 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. - int prev_name_length; // For constructors/destructors. - short nest_level; // For nested names. - bool append; // Append flag. - bool overflowed; // True if output gets overflowed. -} 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) { - size_t len = 0; - while (*str != '\0') { - ++str; - ++len; - } - return len; -} - -// Returns true if "str" has at least "n" characters remaining. -static bool AtLeastNumCharsRemaining(const char *str, int n) { - for (int i = 0; i < n; ++i) { - if (str[i] == '\0') { - return false; - } - } - return true; -} - -// Returns true if "str" has "prefix" as a 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]) { - ++i; - } - return prefix[i] == '\0'; // Consumed everything in "prefix". -} - -static void InitState(State *state, const char *mangled, - char *out, int out_size) { - state->mangled_cur = mangled; - state->out_cur = out; - state->out_begin = out; - state->out_end = out + out_size; - state->prev_name = NULL; - state->prev_name_length = -1; - state->nest_level = -1; - state->append = true; - state->overflowed = false; -} - -// 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) { - if (state->mangled_cur[0] == one_char_token) { - ++state->mangled_cur; - return true; - } - return false; -} - -// 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) { - if (state->mangled_cur[0] == two_char_token[0] && - state->mangled_cur[1] == two_char_token[1]) { - state->mangled_cur += 2; - return true; - } - return false; -} - -// 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; - for (; *p != '\0'; ++p) { - if (state->mangled_cur[0] == *p) { - ++state->mangled_cur; - return true; - } - } - return false; -} - -// This function is used for handling an optional non-terminal. -static bool Optional(bool) { - return true; -} - -// This function is used for handling <non-terminal>+ syntax. -typedef bool (*ParseFunc)(State *); -static bool OneOrMore(ParseFunc parse_func, State *state) { - if (parse_func(state)) { - while (parse_func(state)) { - } - return true; - } - return false; -} - -// This function is used for handling <non-terminal>* syntax. The function -// 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) { - while (parse_func(state)) { - } - return true; -} - -// 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, const int length) { - int i; - for (i = 0; i < length; ++i) { - if (state->out_cur + 1 < state->out_end) { // +1 for '\0' - *state->out_cur = str[i]; - ++state->out_cur; - } else { - state->overflowed = true; - break; - } - } - if (!state->overflowed) { - *state->out_cur = '\0'; // Terminate it with '\0' - } -} - -// We don't use equivalents in libc to avoid locale issues. -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'; -} - -// 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) { - size_t i = 0; - while (str[i] != '\0') { - // Consume a single .<alpha>+.<digit>+ sequence. - if (str[i] != '.' || !IsAlpha(str[i + 1])) { - return false; - } - i += 2; - while (IsAlpha(str[i])) { - ++i; - } - if (str[i] != '.' || !IsDigit(str[i + 1])) { - return false; - } - i += 2; - while (IsDigit(str[i])) { - ++i; - } - } - return true; // Consumed everything in "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, - const int 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 && - state->out_cur[-1] == '<') { - Append(state, " ", 1); - } - // Remember the last identifier name for ctors/dtors. - if (IsAlpha(str[0]) || str[0] == '_') { - state->prev_name = state->out_cur; - state->prev_name_length = length; - } - Append(state, str, length); - } -} - -// A convenient wrapper arount MaybeAppendWithLength(). -static bool MaybeAppend(State *state, const char * const str) { - if (state->append) { - int length = StrLen(str); - MaybeAppendWithLength(state, str, length); - } - return true; -} - -// This function is used for handling nested names. -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) { - state->nest_level = prev_value; - return true; -} - -// Disable the append mode not to print function parameters, etc. -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) { - state->append = prev_value; - return true; -} - -// Increase the nest level for nested names. -static void MaybeIncreaseNestLevel(State *state) { - if (state->nest_level > -1) { - ++state->nest_level; - } -} - -// Appends :: for nested names if necessary. -static void MaybeAppendSeparator(State *state) { - if (state->nest_level >= 1) { - MaybeAppend(state, "::"); - } -} - -// Cancel the last separator if necessary. -static void MaybeCancelLastSeparator(State *state) { - if (state->nest_level >= 1 && state->append && - state->out_begin <= state->out_cur - 2) { - state->out_cur -= 2; - *state->out_cur = '\0'; - } -} - -// Returns true if the identifier of the given length pointed to by -// "mangled_cur" is anonymous namespace. -static bool IdentifierIsAnonymousNamespace(State *state, int length) { - static const char anon_prefix[] = "_GLOBAL__N_"; - return (length > (int)sizeof(anon_prefix) - 1 && // Should be longer. - StrPrefix(state->mangled_cur, anon_prefix)); -} - -// 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, int 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 -// exceptions. -// -// - Support GNU extensions not defined in the Itanium C++ ABI -// - <prefix> and <template-prefix> are combined to avoid infinite loop -// - Reorder patterns to shorten the code -// - Reorder patterns to give greedier functions precedence -// We'll mark "Less greedy than" for these cases in the code -// -// Each parsing function changes the state and returns true on -// success. Otherwise, don't change the state and returns false. To -// ensure that the state isn't changed in the latter case, we save the -// original state before we call more than one parsing functions -// consecutively with &&, and restore the state if unsuccessful. See -// ParseEncoding() as an example of this convention. We follow the -// convention throughout the code. -// -// Originally we tried to do demangling without following the full ABI -// syntax but it turned out we needed to follow the full syntax to -// parse complicated cases like nested template arguments. Note that -// implementing a full-fledged demangler isn't trivial (libiberty's -// cp-demangle.c has +4300 lines). -// -// Note that (foo) in <(foo) ...> is a modifier to be ignored. -// -// Reference: -// - Itanium C++ ABI -// <http://www.codesourcery.com/cxx-abi/abi.html#mangling> - -// <mangled-name> ::= _Z <encoding> -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) { - State copy = *state; - if (ParseName(state) && ParseBareFunctionType(state)) { - return true; - } - *state = copy; - - if (ParseName(state) || ParseSpecialName(state)) { - return true; - } - return false; -} - -// <name> ::= <nested-name> -// ::= <unscoped-template-name> <template-args> -// ::= <unscoped-name> -// ::= <local-name> -static bool ParseName(State *state) { - if (ParseNestedName(state) || ParseLocalName(state)) { - return true; - } - - State copy = *state; - if (ParseUnscopedTemplateName(state) && - ParseTemplateArgs(state)) { - return true; - } - *state = copy; - - // Less greedy than <unscoped-template-name> <template-args>. - if (ParseUnscopedName(state)) { - return true; - } - return false; -} - -// <unscoped-name> ::= <unqualified-name> -// ::= St <unqualified-name> -static bool ParseUnscopedName(State *state) { - if (ParseUnqualifiedName(state)) { - return true; - } - - State copy = *state; - if (ParseTwoCharToken(state, "St") && - MaybeAppend(state, "std::") && - ParseUnqualifiedName(state)) { - return true; - } - *state = copy; - return false; -} - -// <unscoped-template-name> ::= <unscoped-name> -// ::= <substitution> -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) { - State copy = *state; - if (ParseOneCharToken(state, 'N') && - EnterNestedName(state) && - Optional(ParseCVQualifiers(state)) && - ParsePrefix(state) && - LeaveNestedName(state, copy.nest_level) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - return false; -} - -// This part is tricky. If we literally translate them to code, we'll -// end up infinite loop. Hence we merge them to avoid the case. -// -// <prefix> ::= <prefix> <unqualified-name> -// ::= <template-prefix> <template-args> -// ::= <template-param> -// ::= <substitution> -// ::= # empty -// <template-prefix> ::= <prefix> <(template) unqualified-name> -// ::= <template-param> -// ::= <substitution> -static bool ParsePrefix(State *state) { - bool has_something = false; - while (true) { - MaybeAppendSeparator(state); - if (ParseTemplateParam(state) || - ParseSubstitution(state) || - ParseUnscopedName(state)) { - has_something = true; - MaybeIncreaseNestLevel(state); - continue; - } - MaybeCancelLastSeparator(state); - if (has_something && ParseTemplateArgs(state)) { - return ParsePrefix(state); - } else { - break; - } - } - return true; -} - -// <unqualified-name> ::= <operator-name> -// ::= <ctor-dtor-name> -// ::= <source-name> [<abi-tags>] -// ::= <local-source-name> [<abi-tags>] -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) { - State copy = *state; - int length = -1; - if (ParseNumber(state, &length) && ParseIdentifier(state, length)) { - return true; - } - *state = copy; - return false; -} - -// <local-source-name> ::= L <source-name> [<discriminator>] -// -// 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) { - State copy = *state; - if (ParseOneCharToken(state, 'L') && ParseSourceName(state) && - Optional(ParseDiscriminator(state))) { - return true; - } - *state = copy; - return false; -} - -// <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) { - int sign = 1; - if (ParseOneCharToken(state, 'n')) { - sign = -1; - } - const char *p = state->mangled_cur; - int number = 0; - for (;*p != '\0'; ++p) { - if (IsDigit(*p)) { - number = number * 10 + (*p - '0'); - } else { - break; - } - } - if (p != state->mangled_cur) { // Conversion succeeded. - state->mangled_cur = p; - if (number_out != NULL) { - *number_out = number * sign; - } - return true; - } - return false; -} - -// 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) { - if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) { - break; - } - } - if (p != state->mangled_cur) { // Conversion succeeded. - state->mangled_cur = p; - return true; - } - return false; -} - -// 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) { - if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) { - break; - } - } - if (p != state->mangled_cur) { // Conversion succeeded. - state->mangled_cur = p; - return true; - } - return false; -} - -// <identifier> ::= <unqualified source code identifier> (of given length) -static bool ParseIdentifier(State *state, int length) { - if (length == -1 || - !AtLeastNumCharsRemaining(state->mangled_cur, length)) { - return false; - } - if (IdentifierIsAnonymousNamespace(state, length)) { - MaybeAppend(state, "(anonymous namespace)"); - } else { - MaybeAppendWithLength(state, state->mangled_cur, length); - } - state->mangled_cur += length; - return true; -} - -// <abi-tags> ::= <abi-tag> [<abi-tags>] -static bool ParseAbiTags(State *state) { - State copy = *state; - DisableAppend(state); - if (OneOrMore(ParseAbiTag, state)) { - RestoreAppend(state, copy.append); - return true; - } - *state = copy; - return false; -} - -// <abi-tag> ::= B <source-name> -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) { - 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) && - LeaveNestedName(state, copy.nest_level)) { - return true; - } - *state = copy; - - // Then vendor extended operators. - if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") && - ParseSourceName(state)) { - return true; - } - *state = copy; - - // 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]))) { - return false; - } - // We may want to perform a binary search if we really need speed. - const AbbrevPair *p; - for (p = kOperatorList; p->abbrev != NULL; ++p) { - if (state->mangled_cur[0] == p->abbrev[0] && - state->mangled_cur[1] == p->abbrev[1]) { - MaybeAppend(state, "operator"); - if (IsLower(*p->real_name)) { // new, delete, etc. - MaybeAppend(state, " "); - } - MaybeAppend(state, p->real_name); - state->mangled_cur += 2; - return true; - } - } - return false; -} - -// <special-name> ::= TV <type> -// ::= TT <type> -// ::= TI <type> -// ::= TS <type> -// ::= Tc <call-offset> <call-offset> <(base) encoding> -// ::= GV <(object) name> -// ::= T <call-offset> <(base) encoding> -// G++ extensions: -// ::= TC <type> <(offset) number> _ <(base) type> -// ::= TF <type> -// ::= TJ <type> -// ::= GR <name> -// ::= GA <encoding> -// ::= Th <call-offset> <(base) encoding> -// ::= Tv <call-offset> <(base) encoding> -// -// 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) { - State copy = *state; - if (ParseOneCharToken(state, 'T') && - ParseCharClass(state, "VTIS") && - ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) && - ParseCallOffset(state) && ParseEncoding(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "GV") && - ParseName(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) && - ParseEncoding(state)) { - return true; - } - *state = copy; - - // G++ extensions - if (ParseTwoCharToken(state, "TC") && ParseType(state) && - ParseNumber(state, NULL) && ParseOneCharToken(state, '_') && - DisableAppend(state) && - ParseType(state)) { - RestoreAppend(state, copy.append); - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") && - ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "GR") && ParseName(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") && - ParseCallOffset(state) && ParseEncoding(state)) { - return true; - } - *state = copy; - return false; -} - -// <call-offset> ::= h <nv-offset> _ -// ::= v <v-offset> _ -static bool ParseCallOffset(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'h') && - ParseNVOffset(state) && ParseOneCharToken(state, '_')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'v') && - ParseVOffset(state) && ParseOneCharToken(state, '_')) { - return true; - } - *state = copy; - - return false; -} - -// <nv-offset> ::= <(offset) number> -static bool ParseNVOffset(State *state) { - return ParseNumber(state, NULL); -} - -// <v-offset> ::= <(offset) number> _ <(virtual offset) number> -static bool ParseVOffset(State *state) { - State copy = *state; - if (ParseNumber(state, NULL) && ParseOneCharToken(state, '_') && - ParseNumber(state, NULL)) { - return true; - } - *state = copy; - return false; -} - -// <ctor-dtor-name> ::= C1 | C2 | C3 -// ::= D0 | D1 | D2 -static bool ParseCtorDtorName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'C') && - ParseCharClass(state, "123")) { - const char * const prev_name = state->prev_name; - const int 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; - const int prev_name_length = state->prev_name_length; - MaybeAppend(state, "~"); - MaybeAppendWithLength(state, prev_name, prev_name_length); - return true; - } - *state = copy; - return false; -} - -// <type> ::= <CV-qualifiers> <type> -// ::= P <type> # pointer-to -// ::= R <type> # reference-to -// ::= O <type> # rvalue reference-to (C++0x) -// ::= C <type> # complex pair (C 2000) -// ::= G <type> # imaginary (C 2000) -// ::= U <source-name> <type> # vendor extended type qualifier -// ::= <builtin-type> -// ::= <function-type> -// ::= <class-enum-type> -// ::= <array-type> -// ::= <pointer-to-member-type> -// ::= <template-template-param> <template-args> -// ::= <template-param> -// ::= <substitution> -// ::= Dp <type> # pack expansion of (C++0x) -// ::= Dt <expression> E # decltype of an id-expression or class -// # member access (C++0x) -// ::= DT <expression> E # decltype of an expression (C++0x) -// -static bool ParseType(State *state) { - // We should check CV-qualifers, and PRGC things first. - State copy = *state; - if (ParseCVQualifiers(state) && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseCharClass(state, "OPRCG") && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "Dp") && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") && - ParseExpression(state) && ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'U') && ParseSourceName(state) && - ParseType(state)) { - return true; - } - *state = copy; - - if (ParseBuiltinType(state) || - ParseFunctionType(state) || - ParseClassEnumType(state) || - ParseArrayType(state) || - ParsePointerToMemberType(state) || - ParseSubstitution(state)) { - return true; - } - - if (ParseTemplateTemplateParam(state) && - ParseTemplateArgs(state)) { - return true; - } - *state = copy; - - // Less greedy than <template-template-param> <template-args>. - if (ParseTemplateParam(state)) { - return true; - } - - return false; -} - -// <CV-qualifiers> ::= [r] [V] [K] -// We don't allow empty <CV-qualifiers> to avoid infinite loop in -// ParseType(). -static bool ParseCVQualifiers(State *state) { - int num_cv_qualifiers = 0; - num_cv_qualifiers += ParseOneCharToken(state, 'r'); - num_cv_qualifiers += ParseOneCharToken(state, 'V'); - num_cv_qualifiers += ParseOneCharToken(state, 'K'); - return num_cv_qualifiers > 0; -} - -// <builtin-type> ::= v, etc. -// ::= u <source-name> -static bool ParseBuiltinType(State *state) { - const AbbrevPair *p; - for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) { - if (state->mangled_cur[0] == p->abbrev[0]) { - MaybeAppend(state, p->real_name); - ++state->mangled_cur; - return true; - } - } - - State copy = *state; - if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) { - return true; - } - *state = copy; - return false; -} - -// <function-type> ::= F [Y] <bare-function-type> E -static bool ParseFunctionType(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'F') && - Optional(ParseOneCharToken(state, 'Y')) && - ParseBareFunctionType(state) && ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - return false; -} - -// <bare-function-type> ::= <(signature) type>+ -static bool ParseBareFunctionType(State *state) { - State copy = *state; - DisableAppend(state); - if (OneOrMore(ParseType, state)) { - RestoreAppend(state, copy.append); - MaybeAppend(state, "()"); - return true; - } - *state = copy; - return false; -} - -// <class-enum-type> ::= <name> -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) { - State copy = *state; - if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) && - ParseOneCharToken(state, '_') && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) && - ParseOneCharToken(state, '_') && ParseType(state)) { - return true; - } - *state = copy; - return false; -} - -// <pointer-to-member-type> ::= M <(class) type> <(member) type> -static bool ParsePointerToMemberType(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'M') && ParseType(state) && - ParseType(state)) { - return true; - } - *state = copy; - return false; -} - -// <template-param> ::= T_ -// ::= T <parameter-2 non-negative number> _ -static bool ParseTemplateParam(State *state) { - if (ParseTwoCharToken(state, "T_")) { - MaybeAppend(state, "?"); // We don't support template substitutions. - return true; - } - - State copy = *state; - if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) && - ParseOneCharToken(state, '_')) { - MaybeAppend(state, "?"); // We don't support template substitutions. - return true; - } - *state = copy; - return false; -} - - -// <template-template-param> ::= <template-param> -// ::= <substitution> -static bool ParseTemplateTemplateParam(State *state) { - return (ParseTemplateParam(state) || - ParseSubstitution(state)); -} - -// <template-args> ::= I <template-arg>+ E -static bool ParseTemplateArgs(State *state) { - State copy = *state; - DisableAppend(state); - if (ParseOneCharToken(state, 'I') && - OneOrMore(ParseTemplateArg, state) && - ParseOneCharToken(state, 'E')) { - RestoreAppend(state, copy.append); - MaybeAppend(state, "<>"); - return true; - } - *state = copy; - return false; -} - -// <template-arg> ::= <type> -// ::= <expr-primary> -// ::= I <template-arg>* E # argument pack -// ::= J <template-arg>* E # argument pack -// ::= X <expression> E -static bool ParseTemplateArg(State *state) { - State copy = *state; - if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) && - ZeroOrMore(ParseTemplateArg, state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseType(state) || - ParseExprPrimary(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'X') && ParseExpression(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - return false; -} - -// <expression> ::= <template-param> -// ::= <expr-primary> -// ::= <unary operator-name> <expression> -// ::= <binary operator-name> <expression> <expression> -// ::= <trinary operator-name> <expression> <expression> -// <expression> -// ::= st <type> -// ::= sr <type> <unqualified-name> <template-args> -// ::= sr <type> <unqualified-name> -static bool ParseExpression(State *state) { - if (ParseTemplateParam(state) || ParseExprPrimary(state)) { - return true; - } - - State copy = *state; - if (ParseOperatorName(state) && - ParseExpression(state) && - ParseExpression(state) && - ParseExpression(state)) { - return true; - } - *state = copy; - - if (ParseOperatorName(state) && - ParseExpression(state) && - ParseExpression(state)) { - return true; - } - *state = copy; - - if (ParseOperatorName(state) && - ParseExpression(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "st") && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "sr") && ParseType(state) && - ParseUnqualifiedName(state) && - ParseTemplateArgs(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "sr") && ParseType(state) && - ParseUnqualifiedName(state)) { - return true; - } - *state = copy; - return false; -} - -// <expr-primary> ::= L <type> <(value) number> E -// ::= L <type> <(value) float> E -// ::= L <mangled-name> E -// // A bug in g++'s C++ ABI version 2 (-fabi-version=2). -// ::= LZ <encoding> E -static bool ParseExprPrimary(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'L') && ParseType(state) && - ParseNumber(state, NULL) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'L') && ParseType(state) && - ParseFloatNumber(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'L') && ParseMangledName(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - return false; -} - -// <local-name> := Z <(function) encoding> E <(entity) name> -// [<discriminator>] -// := Z <(function) encoding> E s [<discriminator>] -static bool ParseLocalName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && - ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") && - ParseName(state) && Optional(ParseDiscriminator(state))) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && - ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) { - return true; - } - *state = copy; - return false; -} - -// <discriminator> := _ <(non-negative) number> -static bool ParseDiscriminator(State *state) { - State copy = *state; - if (ParseOneCharToken(state, '_') && ParseNumber(state, NULL)) { - return true; - } - *state = copy; - return false; -} - -// <substitution> ::= S_ -// ::= S <seq-id> _ -// ::= St, etc. -static bool ParseSubstitution(State *state) { - if (ParseTwoCharToken(state, "S_")) { - MaybeAppend(state, "?"); // We don't support substitutions. - return true; - } - - State copy = *state; - if (ParseOneCharToken(state, 'S') && ParseSeqId(state) && - ParseOneCharToken(state, '_')) { - MaybeAppend(state, "?"); // We don't support substitutions. - return true; - } - *state = copy; - - // Expand abbreviations like "St" => "std". - if (ParseOneCharToken(state, 'S')) { - const AbbrevPair *p; - for (p = kSubstitutionList; p->abbrev != NULL; ++p) { - if (state->mangled_cur[0] == p->abbrev[1]) { - MaybeAppend(state, "std"); - if (p->real_name[0] != '\0') { - MaybeAppend(state, "::"); - MaybeAppend(state, p->real_name); - } - ++state->mangled_cur; - return true; - } - } - } - *state = copy; - return false; -} - -// 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) { - if (ParseMangledName(state)) { - if (state->mangled_cur[0] != '\0') { - // Drop trailing function clone suffix, if any. - if (IsFunctionCloneSuffix(state->mangled_cur)) { - return true; - } - // Append trailing version suffix if any. - // ex. _Z3foo@@GLIBCXX_3.4 - if (state->mangled_cur[0] == '@') { - MaybeAppend(state, state->mangled_cur); - return true; - } - return false; // Unconsumed suffix. - } - return true; - } - return false; -} -#endif - -// The demangler entry point. -bool Demangle(const char *mangled, char *out, int out_size) { -#if defined(OS_WINDOWS) - // When built with incremental linking, the Windows debugger - // library provides a more complicated `Symbol->Name` with the - // Incremental Linking Table offset, which looks like - // `@ILT+1105(?func@Foo@@SAXH@Z)`. However, the demangler expects - // only the mangled symbol, `?func@Foo@@SAXH@Z`. Fortunately, the - // mangled symbol is guaranteed not to have parentheses, - // so we search for `(` and extract up to `)`. - // - // 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, '('); - if (lparen) { - // Extract the string `(?...)` - const char *rparen = strchr(lparen, ')'); - size_t length = rparen - lparen - 1; - strncpy(buffer, lparen + 1, length); - buffer[length] = '\0'; - mangled = buffer; - } // 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 - State state; - InitState(&state, mangled, out, out_size); - return ParseTopLevelMangledName(&state) && !state.overflowed; -#endif -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/demangle.h b/third_party/glog/src/demangle.h deleted file mode 100644 index 991b6ffcf2e6..000000000000 --- a/third_party/glog/src/demangle.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// An async-signal-safe and thread-safe demangler for Itanium C++ ABI -// (aka G++ V3 ABI). - -// The demangler is implemented to be used in async signal handlers to -// symbolize stack traces. We cannot use libstdc++'s -// abi::__cxa_demangle() in such signal handlers since it's not async -// signal safe (it uses malloc() internally). -// -// Note that this demangler doesn't support full demangling. More -// specifically, it doesn't print types of function parameters and -// types of template arguments. It just skips them. However, it's -// still very useful to extract basic information such as class, -// function, constructor, destructor, and operator names. -// -// See the implementation note in demangle.cc if you are interested. -// -// Example: -// -// | Mangled Name | The Demangler | abi::__cxa_demangle() -// |---------------|---------------|----------------------- -// | _Z1fv | f() | f() -// | _Z1fi | f() | f(int) -// | _Z3foo3bar | foo() | foo(bar) -// | _Z1fIiEvi | f<>() | void f<int>(int) -// | _ZN1N1fE | N::f | N::f -// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar() -// | _Zrm1XS_" | operator%() | operator%(X, X) -// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo() -// | _Z1fSs | f() | f(std::basic_string<char, -// | | | std::char_traits<char>, -// | | | std::allocator<char> >) -// -// See the unit test for more examples. -// -// Note: we might want to write demanglers for ABIs other than Itanium -// C++ ABI in the future. -// - -#ifndef BASE_DEMANGLE_H_ -#define BASE_DEMANGLE_H_ - -#include "config.h" -#include "glog/logging.h" - -_START_GOOGLE_NAMESPACE_ - -// Demangle "mangled". On success, return true and write the -// demangled symbol name to "out". Otherwise, return false. -// "out" is modified even if demangling is unsuccessful. -bool GOOGLE_GLOG_DLL_DECL Demangle(const char *mangled, char *out, int out_size); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_DEMANGLE_H_ diff --git a/third_party/glog/src/demangle_unittest.cc b/third_party/glog/src/demangle_unittest.cc deleted file mode 100644 index be483411f1a0..000000000000 --- a/third_party/glog/src/demangle_unittest.cc +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// Unit tests for functions in demangle.c. - -#include "utilities.h" - -#include <iostream> -#include <fstream> -#include <string> -#include "glog/logging.h" -#include "demangle.h" -#include "googletest.h" -#include "config.h" - -#ifdef HAVE_LIB_GFLAGS -#include <gflags/gflags.h> -using namespace GFLAGS_NAMESPACE; -#endif - -GLOG_DEFINE_bool(demangle_filter, false, - "Run demangle_unittest in filter mode"); - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -// A wrapper function for Demangle() to make the unit test simple. -static const char *DemangleIt(const char * const mangled) { - static char demangled[4096]; - if (Demangle(mangled, demangled, sizeof(demangled))) { - return demangled; - } else { - return mangled; - } -} - -#if defined(OS_WINDOWS) - -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")); -} - -#else - -// Test corner cases of bounary conditions. -TEST(Demangle, CornerCases) { - const size_t size = 10; - char tmp[size] = { 0 }; - const char *demangled = "foobar()"; - const char *mangled = "_Z6foobarv"; - EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp))); - // sizeof("foobar()") == size - 1 - EXPECT_STREQ(demangled, tmp); - EXPECT_TRUE(Demangle(mangled, tmp, size - 1)); - EXPECT_STREQ(demangled, tmp); - EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough. - EXPECT_FALSE(Demangle(mangled, tmp, 1)); - EXPECT_FALSE(Demangle(mangled, tmp, 0)); - EXPECT_FALSE(Demangle(mangled, NULL, 0)); // Should not cause SEGV. -} - -// Test handling of functions suffixed with .clone.N, which is used by GCC -// 4.5.x, and .constprop.N and .isra.N, which are used by GCC 4.6.x. These -// suffixes are used to indicate functions which have been cloned during -// optimization. We ignore these suffixes. -TEST(Demangle, Clones) { - char tmp[20]; - EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - // Invalid (truncated), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp))); - // Invalid (.clone. not followed by number), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp))); - // Invalid (.clone. followed by non-number), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp))); - // Invalid (.constprop. not followed by number), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp))); -} - -TEST(Demangle, FromFile) { - string test_file = FLAGS_test_srcdir + "/src/demangle_unittest.txt"; - ifstream f(test_file.c_str()); // The file should exist. - EXPECT_FALSE(f.fail()); - - string line; - while (getline(f, line)) { - // Lines start with '#' are considered as comments. - if (line.empty() || line[0] == '#') { - continue; - } - // Each line should contain a mangled name and a demangled name - // separated by '\t'. Example: "_Z3foo\tfoo" - string::size_type tab_pos = line.find('\t'); - EXPECT_NE(string::npos, tab_pos); - string mangled = line.substr(0, tab_pos); - string demangled = line.substr(tab_pos + 1); - EXPECT_EQ(demangled, DemangleIt(mangled.c_str())); - } -} - -#endif - -int main(int argc, char **argv) { -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#endif - InitGoogleTest(&argc, argv); - - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - if (FLAGS_demangle_filter) { - // Read from cin and write to cout. - string line; - while (getline(cin, line, '\n')) { - cout << DemangleIt(line.c_str()) << endl; - } - return 0; - } else if (argc > 1) { - cout << DemangleIt(argv[1]) << endl; - return 0; - } else { - return RUN_ALL_TESTS(); - } -} diff --git a/third_party/glog/src/demangle_unittest.sh b/third_party/glog/src/demangle_unittest.sh deleted file mode 100755 index 91deee2198da..000000000000 --- a/third_party/glog/src/demangle_unittest.sh +++ /dev/null @@ -1,95 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 2006, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Author: Satoru Takabayashi -# -# Unit tests for demangle.c with a real binary. - -set -e - -die () { - echo $1 - exit 1 -} - -BINDIR=".libs" -LIBGLOG="$BINDIR/libglog.so" - -DEMANGLER="$BINDIR/demangle_unittest" - -if test -e "$DEMANGLER"; then - # We need shared object. - export LD_LIBRARY_PATH=$BINDIR - export DYLD_LIBRARY_PATH=$BINDIR -else - # For windows - DEMANGLER="./demangle_unittest.exe" - if ! test -e "$DEMANGLER"; then - echo "We coundn't find demangle_unittest binary." - exit 1 - fi -fi - -# Extract C++ mangled symbols from libbase.so. -NM_OUTPUT="demangle.nm" -nm "$LIBGLOG" | perl -nle 'print $1 if /\s(_Z\S+$)/' > "$NM_OUTPUT" - -# Check if mangled symbols exist. If there are none, we quit. -# The binary is more likely compiled with GCC 2.95 or something old. -if ! grep --quiet '^_Z' "$NM_OUTPUT"; then - echo "PASS" - exit 0 -fi - -# Demangle the symbols using our demangler. -DM_OUTPUT="demangle.dm" -GLOG_demangle_filter=1 "$DEMANGLER" --demangle_filter < "$NM_OUTPUT" > "$DM_OUTPUT" - -# Calculate the numbers of lines. -NM_LINES=`wc -l "$NM_OUTPUT" | awk '{ print $1 }'` -DM_LINES=`wc -l "$DM_OUTPUT" | awk '{ print $1 }'` - -# Compare the numbers of lines. They must be the same. -if test "$NM_LINES" != "$DM_LINES"; then - die "$NM_OUTPUT and $DM_OUTPUT don't have the same numbers of lines" -fi - -# Check if mangled symbols exist. They must not exist. -if grep --quiet '^_Z' "$DM_OUTPUT"; then - MANGLED=`grep '^_Z' "$DM_OUTPUT" | wc -l | awk '{ print \$1 }'` - echo "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT:" - grep '^_Z' "$DM_OUTPUT" - die "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT" -fi - -# All C++ symbols are demangled successfully. -echo "PASS" -exit 0 diff --git a/third_party/glog/src/demangle_unittest.txt b/third_party/glog/src/demangle_unittest.txt deleted file mode 100644 index 07e28bce2f8f..000000000000 --- a/third_party/glog/src/demangle_unittest.txt +++ /dev/null @@ -1,145 +0,0 @@ -# Test caces for demangle_unittest. Each line consists of a -# tab-separated pair of mangled and demangled symbol names. - -# Constructors and destructors. -_ZN3FooC1Ev Foo::Foo() -_ZN3FooD1Ev Foo::~Foo() -_ZNSoD0Ev std::ostream::~ostream() - -# G++ extensions. -_ZTCN10LogMessage9LogStreamE0_So LogMessage::LogStream -_ZTv0_n12_N10LogMessage9LogStreamD0Ev LogMessage::LogStream::~LogStream() -_ZThn4_N7icu_3_410UnicodeSetD0Ev icu_3_4::UnicodeSet::~UnicodeSet() - -# A bug in g++'s C++ ABI version 2 (-fabi-version=2). -_ZN7NSSInfoI5groupjjXadL_Z10getgrgid_rEELZ19nss_getgrgid_r_nameEEC1Ei NSSInfo<>::NSSInfo() - -# C linkage symbol names. Should keep them untouched. -main main -Demangle Demangle -_ZERO _ZERO - -# Cast operator. -_Zcviv operator int() -_ZN3foocviEv foo::operator int() - -# Versioned symbols. -_Z3Foo@GLIBCXX_3.4 Foo@GLIBCXX_3.4 -_Z3Foo@@GLIBCXX_3.4 Foo@@GLIBCXX_3.4 - -# Abbreviations. -_ZNSaE std::allocator -_ZNSbE std::basic_string -_ZNSdE std::iostream -_ZNSiE std::istream -_ZNSoE std::ostream -_ZNSsE std::string - -# Substitutions. We just replace them with ?. -_ZN3fooS_E foo::? -_ZN3foo3barS0_E foo::bar::? -_ZNcvT_IiEEv operator ?<>() - -# "<< <" case. -_ZlsI3fooE operator<< <> - -# ABI tags. -_Z1AB3barB3foo A -_ZN3fooL3barB5cxx11E foo::bar - -# Random things we found interesting. -_ZN3FooISt6vectorISsSaISsEEEclEv Foo<>::operator()() -_ZTI9Callback1IiE Callback1<> -_ZN7icu_3_47UMemorynwEj icu_3_4::UMemory::operator new() -_ZNSt6vectorIbE9push_backE std::vector<>::push_back -_ZNSt6vectorIbSaIbEE9push_backEb std::vector<>::push_back() -_ZlsRSoRK15PRIVATE_Counter operator<<() -_ZSt6fill_nIPPN9__gnu_cxx15_Hashtable_nodeISt4pairIKPKcjEEEjS8_ET_SA_T0_RKT1_ std::fill_n<>() -_ZZ3FoovE3Bar Foo()::Bar -_ZGVZ7UpTimervE8up_timer UpTimer()::up_timer - -# Test cases from gcc-4.1.0/libstdc++-v3/testsuite/demangle. -# Collected by: -# % grep verify_demangle **/*.cc | perl -nle 'print $1 if /"(_Z.*?)"/' | -# sort | uniq -# -# Note that the following symbols are invalid. -# That's why they are not demangled. -# - _ZNZN1N1fEiE1X1gE -# - _ZNZN1N1fEiE1X1gEv -# - _Z1xINiEE -_Z1fA37_iPS_ f() -_Z1fAszL_ZZNK1N1A1fEvE3foo_0E_i f() -_Z1fI1APS0_PKS0_EvT_T0_T1_PA4_S3_M1CS8_ f<>() -_Z1fI1XENT_1tES2_ f<>() -_Z1fI1XEvPVN1AIT_E1TE f<>() -_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE f<>() -_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE f<>() -_Z1fILi5E1AEvN1CIXqugtT_Li0ELi1ELi2EEE1qE f<>() -_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE f<>() -_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE f<>() -_Z1fIiEvi f<>() -_Z1fKPFiiE f() -_Z1fM1AFivEPS0_ f() -_Z1fM1AKFivE f() -_Z1fM1AKFvvE f() -_Z1fPFPA1_ivE f() -_Z1fPFYPFiiEiE f() -_Z1fPFvvEM1SFvvE f() -_Z1fPKM1AFivE f() -_Z1fi f() -_Z1fv f() -_Z1jM1AFivEPS1_ j() -_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_ r() -_Z1sPA37_iPS0_ s() -_Z1xINiEE _Z1xINiEE -_Z3absILi11EEvv abs<>() -_Z3foo3bar foo() -_Z3foo5Hello5WorldS0_S_ foo() -_Z3fooA30_A_i foo() -_Z3fooIA6_KiEvA9_KT_rVPrS4_ foo<>() -_Z3fooILi2EEvRAplT_Li1E_i foo<>() -_Z3fooIiFvdEiEvv foo<>() -_Z3fooPM2ABi foo() -_Z3fooc foo() -_Z3fooiPiPS_PS0_PS1_PS2_PS3_PS4_PS5_PS6_PS7_PS8_PS9_PSA_PSB_PSC_ foo() -_Z3kooPA28_A30_i koo() -_Z4makeI7FactoryiET_IT0_Ev make<>() -_Z5firstI3DuoEvS0_ first<>() -_Z5firstI3DuoEvT_ first<>() -_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE hairyfunc() -_ZGVN5libcw24_GLOBAL__N_cbll.cc0ZhUKa23compiler_bug_workaroundISt6vectorINS_13omanip_id_tctINS_5debug32memblk_types_manipulator_data_ctEEESaIS6_EEE3idsE libcw::(anonymous namespace)::compiler_bug_workaround<>::ids -_ZN12libcw_app_ct10add_optionIS_EEvMT_FvPKcES3_cS3_S3_ libcw_app_ct::add_option<>() -_ZN1AIfEcvT_IiEEv A<>::operator ?<>() -_ZN1N1TIiiE2mfES0_IddE N::T<>::mf() -_ZN1N1fE N::f -_ZN1f1fE f::f -_ZN3FooIA4_iE3barE Foo<>::bar -_ZN5Arena5levelE Arena::level -_ZN5StackIiiE5levelE Stack<>::level -_ZN5libcw5debug13cwprint_usingINS_9_private_12GlobalObjectEEENS0_17cwprint_using_tctIT_EERKS5_MS5_KFvRSt7ostreamE libcw::debug::cwprint_using<>() -_ZN6System5Sound4beepEv System::Sound::beep() -_ZNKSt14priority_queueIP27timer_event_request_base_ctSt5dequeIS1_SaIS1_EE13timer_greaterE3topEv std::priority_queue<>::top() -_ZNKSt15_Deque_iteratorIP15memory_block_stRKS1_PS2_EeqERKS5_ std::_Deque_iterator<>::operator==() -_ZNKSt17__normal_iteratorIPK6optionSt6vectorIS0_SaIS0_EEEmiERKS6_ std::__normal_iterator<>::operator-() -_ZNSbIcSt11char_traitsIcEN5libcw5debug27no_alloc_checking_allocatorEE12_S_constructIPcEES6_T_S7_RKS3_ std::basic_string<>::_S_construct<>() -_ZNSt13_Alloc_traitsISbIcSt18string_char_traitsIcEN5libcw5debug9_private_17allocator_adaptorIcSt24__default_alloc_templateILb0ELi327664EELb1EEEENS5_IS9_S7_Lb1EEEE15_S_instancelessE std::_Alloc_traits<>::_S_instanceless -_ZNSt3_In4wardE std::_In::ward -_ZNZN1N1fEiE1X1gE _ZNZN1N1fEiE1X1gE -_ZNZN1N1fEiE1X1gEv _ZNZN1N1fEiE1X1gEv -_ZSt1BISt1DIP1ARKS2_PS3_ES0_IS2_RS2_PS2_ES2_ET0_T_SB_SA_PT1_ std::B<>() -_ZSt5state std::state -_ZTI7a_class a_class -_ZZN1N1fEiE1p N::f()::p -_ZZN1N1fEiEs N::f() -_ZlsRK1XS1_ operator<<() -_ZlsRKU3fooU4bart1XS0_ operator<<() -_ZlsRKU3fooU4bart1XS2_ operator<<() -_ZlsRSoRKSs operator<<() -_ZngILi42EEvN1AIXplT_Li2EEE1TE operator-<>() -_ZplR1XS0_ operator+() -_Zrm1XS_ operator%() - -# Template argument packs can start with I or J. -_Z3addIIiEEvDpT_ add<>() -_Z3addIJiEEvDpT_ add<>() diff --git a/third_party/glog/src/glog/log_severity.h b/third_party/glog/src/glog/log_severity.h deleted file mode 100644 index 987cc57dae91..000000000000 --- a/third_party/glog/src/glog/log_severity.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef BASE_LOG_SEVERITY_H__ -#define BASE_LOG_SEVERITY_H__ - -// The recommended semantics of the log levels are as follows: -// -// INFO: -// Use for state changes or other major events, or to aid debugging. -// WARNING: -// Use for undesired but relatively expected events, which may indicate a -// problem -// ERROR: -// Use for undesired and unexpected events that the program can recover from. -// All ERRORs should be actionable - it should be appropriate to file a bug -// whenever an ERROR occurs in production. -// FATAL: -// Use for undesired and unexpected events that the program cannot recover -// from. - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// Variables of type LogSeverity are widely taken to lie in the range -// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if -// you ever need to change their values or add a new severity. -typedef int LogSeverity; - -const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3, - NUM_SEVERITIES = 4; -#ifndef GLOG_NO_ABBREVIATED_SEVERITIES -# ifdef ERROR -# error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail. -# endif -const int INFO = GLOG_INFO, WARNING = GLOG_WARNING, - ERROR = GLOG_ERROR, FATAL = GLOG_FATAL; -#endif - -// DFATAL is FATAL in debug mode, ERROR in normal mode -#ifdef NDEBUG -#define DFATAL_LEVEL ERROR -#else -#define DFATAL_LEVEL FATAL -#endif - -extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; - -// NDEBUG usage helpers related to (RAW_)DCHECK: -// -// DEBUG_MODE is for small !NDEBUG uses like -// if (DEBUG_MODE) foo.CheckThatFoo(); -// instead of substantially more verbose -// #ifndef NDEBUG -// foo.CheckThatFoo(); -// #endif -// -// IF_DEBUG_MODE is for small !NDEBUG uses like -// IF_DEBUG_MODE( string error; ) -// DCHECK(Foo(&error)) << error; -// instead of substantially more verbose -// #ifndef NDEBUG -// string error; -// DCHECK(Foo(&error)) << error; -// #endif -// -#ifdef NDEBUG -enum { DEBUG_MODE = 0 }; -#define IF_DEBUG_MODE(x) -#else -enum { DEBUG_MODE = 1 }; -#define IF_DEBUG_MODE(x) x -#endif - -#endif // BASE_LOG_SEVERITY_H__ diff --git a/third_party/glog/src/glog/logging.h.in b/third_party/glog/src/glog/logging.h.in deleted file mode 100644 index 1e552fc1a177..000000000000 --- a/third_party/glog/src/glog/logging.h.in +++ /dev/null @@ -1,1689 +0,0 @@ -// Copyright (c) 1999, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Ray Sidney -// -// This file contains #include information about logging-related stuff. -// Pretty much everybody needs to #include this file so that they can -// log various happenings. -// -#ifndef _LOGGING_H_ -#define _LOGGING_H_ - -#include <errno.h> -#include <string.h> -#include <time.h> -#include <iosfwd> -#include <ostream> -#include <sstream> -#include <string> -#if @ac_cv_have_unistd_h@ -# include <unistd.h> -#endif -#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)) -#else -#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) -#define GLOG_MSVC_POP_WARNING() -#endif - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// We care a lot about number of bits things take up. Unfortunately, -// systems define their bit-specific ints in a lot of different ways. -// We use our own way, and have a typedef to get there. -// Note: these commands below may look like "#if 1" or "#if 0", but -// that's because they were constructed that way at ./configure time. -// Look at logging.h.in to see how they're calculated (based on your config). -#if @ac_cv_have_stdint_h@ -#include <stdint.h> // the normal place uint16_t is defined -#endif -#if @ac_cv_have_systypes_h@ -#include <sys/types.h> // the normal place u_int16_t is defined -#endif -#if @ac_cv_have_inttypes_h@ -#include <inttypes.h> // a third place for uint16_t or u_int16_t -#endif - -#if @ac_cv_have_libgflags@ -#include <gflags/gflags.h> -#endif - -@ac_google_start_namespace@ - -#if @ac_cv_have_uint16_t@ // the C99 format -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#elif @ac_cv_have_u_int16_t@ // the BSD format -typedef int32_t int32; -typedef u_int32_t uint32; -typedef int64_t int64; -typedef u_int64_t uint64; -#elif @ac_cv_have___uint16@ // the windows (vc7) format -typedef __int32 int32; -typedef unsigned __int32 uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; -#else -#error Do not know how to define a 32-bit integer quantity on your system -#endif - -@ac_google_end_namespace@ - -// The global value of GOOGLE_STRIP_LOG. All the messages logged to -// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. -// If it can be determined at compile time that the message will not be -// printed, the statement will be compiled out. -// -// Example: to strip out all INFO and WARNING messages, use the value -// of 2 below. To make an exception for WARNING messages from a single -// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including -// base/logging.h -#ifndef GOOGLE_STRIP_LOG -#define GOOGLE_STRIP_LOG 0 -#endif - -// GCC can be told that a certain branch is not likely to be taken (for -// instance, a CHECK failure), and use that information in static analysis. -// Giving it this information can help it optimize for the common case in -// the absence of better information (ie. -fprofile-arcs). -// -#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN -#if @ac_cv_have___builtin_expect@ -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x -#endif -#endif - -#ifndef GOOGLE_PREDICT_FALSE -#if @ac_cv_have___builtin_expect@ -#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_FALSE(x) x -#endif -#endif - -#ifndef GOOGLE_PREDICT_TRUE -#if @ac_cv_have___builtin_expect@ -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#define GOOGLE_PREDICT_TRUE(x) x -#endif -#endif - - -// Make a bunch of macros for logging. The way to log things is to stream -// things to LOG(<a particular severity level>). E.g., -// -// LOG(INFO) << "Found " << num_cookies << " cookies"; -// -// You can capture log messages in a string, rather than reporting them -// immediately: -// -// vector<string> errors; -// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; -// -// This pushes back the new error onto 'errors'; if given a NULL pointer, -// it reports the error via LOG(ERROR). -// -// You can also do conditional logging: -// -// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// You can also do occasional logging (log every n'th occurrence of an -// event): -// -// LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// The above will cause log messages to be output on the 1st, 11th, 21st, ... -// times it is executed. Note that the special google::COUNTER value is used -// to identify which repetition is happening. -// -// You can also do occasional conditional logging (log every n'th -// occurrence of an event, when condition is satisfied): -// -// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER -// << "th big cookie"; -// -// You can log messages the first N times your code executes a line. E.g. -// -// LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; -// -// Outputs log messages for the first 20 times it is executed. -// -// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. -// These log to syslog as well as to the normal logs. If you use these at -// all, you need to be aware that syslog can drastically reduce performance, -// especially if it is configured for remote logging! Don't use these -// unless you fully understand this and have a concrete need to use them. -// Even then, try to minimize your use of them. -// -// There are also "debug mode" logging macros like the ones above: -// -// DLOG(INFO) << "Found cookies"; -// -// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// All "debug mode" logging is compiled away to nothing for non-debug mode -// compiles. -// -// We also have -// -// LOG_ASSERT(assertion); -// DLOG_ASSERT(assertion); -// -// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; -// -// There are "verbose level" logging macros. They look like -// -// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; -// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; -// -// These always log at the INFO log level (when they log at all). -// The verbose logging can also be turned on module-by-module. For instance, -// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 -// will cause: -// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} -// b. VLOG(1) and lower messages to be printed from file.{h,cc} -// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" -// d. VLOG(0) and lower messages to be printed from elsewhere -// -// The wildcarding functionality shown by (c) supports both '*' (match -// 0 or more characters) and '?' (match any single character) wildcards. -// -// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as -// -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished with just VLOG(2) << ...; -// } -// -// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" -// condition macros for sample cases, when some extra computation and -// preparation for logs is not needed. -// VLOG_IF(1, (size > 1024)) -// << "I'm printed when size is more than 1024 and when you run the " -// "program with --v=1 or more"; -// VLOG_EVERY_N(1, 10) -// << "I'm printed every 10th occurrence, and when you run the program " -// "with --v=1 or more. Present occurence is " << google::COUNTER; -// VLOG_IF_EVERY_N(1, (size > 1024), 10) -// << "I'm printed on every 10th occurence of case when size is more " -// " than 1024, when you run the program with --v=1 or more. "; -// "Present occurence is " << google::COUNTER; -// -// The supported severity levels for macros that allow you to specify one -// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. -// Note that messages of a given severity are logged not only in the -// logfile for that severity, but also in all logfiles of lower severity. -// E.g., a message of severity FATAL will be logged to the logfiles of -// severity FATAL, ERROR, WARNING, and INFO. -// -// There is also the special severity of DFATAL, which logs FATAL in -// debug mode, ERROR in normal mode. -// -// Very important: logging a message at the FATAL severity level causes -// the program to terminate (after the message is logged). -// -// Unless otherwise specified, logs will be written to the filename -// "<program name>.<hostname>.<user name>.log.<severity level>.", followed -// by the date, time, and pid (you can't prevent the date, time, and pid -// from being in the filename). -// -// The logging code takes two flags: -// --v=# set the verbose level -// --logtostderr log all the messages to stderr instead of to logfiles - -// LOG LINE PREFIX FORMAT -// -// Log lines have this form: -// -// Lyyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg... -// -// where the fields are defined as follows: -// -// L A single character, representing the log level -// (eg 'I' for INFO) -// yyyy The year -// mm The month (zero padded; ie May is '05') -// dd The day (zero padded) -// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds -// threadid The space-padded thread ID as returned by GetTID() -// (this matches the PID on Linux) -// file The file name -// line The line number -// msg The user-supplied message -// -// Example: -// -// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog -// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 -// -// NOTE: although the microseconds are useful for comparing events on -// a single machine, clocks on different machines may not be well -// synchronized. Hence, use caution when comparing the low bits of -// timestamps from different machines. - -#ifndef DECLARE_VARIABLE -#define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name, int32) - -// 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 GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#endif - -// Set whether appending a timestamp to the log file name -DECLARE_bool(timestamp_in_logfile_name); - -// Set whether log messages go to stderr instead of logfiles -DECLARE_bool(logtostderr); - -// Set whether log messages go to stderr in addition to logfiles. -DECLARE_bool(alsologtostderr); - -// Set color messages logged to stderr (if supported by terminal). -DECLARE_bool(colorlogtostderr); - -// Log messages at a level >= this flag are automatically sent to -// stderr in addition to log files. -DECLARE_int32(stderrthreshold); - -// Set whether the log prefix should be prepended to each line of output. -DECLARE_bool(log_prefix); - -// Log messages at a level <= this flag are buffered. -// Log messages at a higher level are flushed immediately. -DECLARE_int32(logbuflevel); - -// Sets the maximum number of seconds which logs may be buffered for. -DECLARE_int32(logbufsecs); - -// Log suppression level: messages logged at a lower level than this -// are suppressed. -DECLARE_int32(minloglevel); - -// If specified, logfiles are written into this directory instead of the -// default logging directory. -DECLARE_string(log_dir); - -// Set the log file mode. -DECLARE_int32(logfile_mode); - -// Sets the path of the directory into which to put additional links -// to the log files. -DECLARE_string(log_link); - -DECLARE_int32(v); // in vlog_is_on.cc - -// Sets the maximum log file size (in MB). -DECLARE_int32(max_log_size); - -// Sets whether to avoid logging to the disk if the disk is full. -DECLARE_bool(stop_logging_if_full_disk); - -#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef DECLARE_VARIABLE -#undef DECLARE_bool -#undef DECLARE_int32 -#undef DECLARE_string -#endif - -// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for -// security reasons. See LOG(severtiy) below. - -// A few definitions of macros that don't generate much code. Since -// LOG(INFO) and its ilk are used all over our code, it's -// better to have compact code for these operations. - -#if GOOGLE_STRIP_LOG == 0 -#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, message) -#else -#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::NullStream() -#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 1 -#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING) -#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, message) -#else -#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::NullStream() -#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 2 -#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR) -#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, message) -#else -#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::NullStream() -#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::LogMessageFatal( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, message) -#else -#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::NullStreamFatal() -#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::NullStreamFatal() -#endif - -#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) -#define DCHECK_IS_ON() 0 -#else -#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 -#elif GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL) -#else -#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::NullStreamFatal() -#endif - -#define GOOGLE_LOG_INFO(counter) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_INFO(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_WARNING(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_WARNING(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_ERROR(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_ERROR(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_FATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_FATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_DFATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_DFATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) - -#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 = NULL; \ - LPSTR msg = reinterpret_cast<LPSTR>(&message); \ - DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ - FORMAT_MESSAGE_FROM_SYSTEM, \ - 0, result, 0, msg, 100, NULL); \ - if (message_length > 0) { \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, 0, \ - &@ac_google_namespace@::LogMessage::SendToLog).stream() \ - << reinterpret_cast<const char*>(message); \ - LocalFree(message); \ - } \ - } -#endif - -// We use the preprocessor's merging operator, "##", so that, e.g., -// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny -// subtle difference between ostream member streaming functions (e.g., -// ostream::operator<<(int) and ostream non-member streaming functions -// (e.g., ::operator<<(ostream&, string&): it turns out that it's -// impossible to stream something like a string directly to an unnamed -// ostream. We employ a neat hack by calling the stream() member -// function of LogMessage which seems to avoid the problem. -#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() -#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() - -@ac_google_start_namespace@ - -// They need the definitions of integer types. -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Initialize google's logging library. You will see the program name -// specified by argv0 in log outputs. -GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); - -// Shutdown google's logging library. -GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); - -// Install a function which will be called after LOG(FATAL). -GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); - -// Enable/Disable old log cleaner. -GOOGLE_GLOG_DLL_DECL void EnableLogCleaner(int overdue_days); -GOOGLE_GLOG_DLL_DECL void DisableLogCleaner(); - - -class LogSink; // defined below - -// If a non-NULL sink pointer is given, we push this message to that sink. -// For LOG_TO_SINK we then do normal LOG(severity) logging as well. -// This is useful for capturing messages and passing/storing them -// somewhere more specific than the global log of the process. -// Argument types: -// LogSink* sink; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -#define LOG_TO_SINK(sink, severity) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, \ - @ac_google_namespace@::GLOG_ ## severity, \ - static_cast<@ac_google_namespace@::LogSink*>(sink), true).stream() -#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, \ - @ac_google_namespace@::GLOG_ ## severity, \ - static_cast<@ac_google_namespace@::LogSink*>(sink), false).stream() - -// If a non-NULL string pointer is given, we write this message to that string. -// We then do normal LOG(severity) logging as well. -// This is useful for capturing messages and storing them somewhere more -// specific than the global log of the process. -// Argument types: -// string* message; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -// NOTE: LOG(severity) expands to LogMessage().stream() for the specified -// severity. -#define LOG_TO_STRING(severity, message) \ - LOG_TO_STRING_##severity(static_cast<string*>(message)).stream() - -// If a non-NULL pointer is given, we push the message onto the end -// of a vector of strings; otherwise, we report it with LOG(severity). -// This is handy for capturing messages and perhaps passing them back -// to the caller, rather than reporting them immediately. -// Argument types: -// LogSeverity severity; -// vector<string> *outvec; -// The cast is to disambiguate NULL arguments. -#define LOG_STRING(severity, outvec) \ - LOG_TO_STRING_##severity(static_cast<std::vector<std::string>*>(outvec)).stream() - -#define LOG_IF(severity, condition) \ - static_cast<void>(0), \ - !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) -#define SYSLOG_IF(severity, condition) \ - static_cast<void>(0), \ - !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & SYSLOG(severity) - -#define LOG_ASSERT(condition) \ - LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition -#define SYSLOG_ASSERT(condition) \ - SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition - -// CHECK dies with a fatal error if condition is not true. It is *not* -// controlled by DCHECK_IS_ON(), so the check will be executed regardless of -// compilation mode. Therefore, it is safe to do things like: -// CHECK(fp->Write(x) == 4) -#define CHECK(condition) \ - LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A container for a string pointer which can be evaluated to a bool - -// true iff the pointer is NULL. -struct CheckOpString { - CheckOpString(std::string* str) : str_(str) { } - // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), - // so there's no point in cleaning up str_. - operator bool() const { - return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); - } - std::string* str_; -}; - -// Function is overloaded for integral types to allow static const -// integrals declared in classes and not defined to be used as arguments to -// CHECK* macros. It's not encouraged though. -template <class T> -inline const T& GetReferenceableValue(const T& t) { return t; } -inline char GetReferenceableValue(char t) { return t; } -inline unsigned char GetReferenceableValue(unsigned char t) { return t; } -inline signed char GetReferenceableValue(signed char t) { return t; } -inline short GetReferenceableValue(short t) { return t; } -inline unsigned short GetReferenceableValue(unsigned short t) { return t; } -inline int GetReferenceableValue(int t) { return t; } -inline unsigned int GetReferenceableValue(unsigned int t) { return t; } -inline long GetReferenceableValue(long t) { return t; } -inline unsigned long GetReferenceableValue(unsigned long t) { return t; } -inline long long GetReferenceableValue(long long t) { return t; } -inline unsigned long long GetReferenceableValue(unsigned long long t) { - return t; -} - -// This is a dummy class to define the following operator. -struct DummyClassToDefineOperator {}; - -@ac_google_end_namespace@ - -// Define global operator<< to declare using ::operator<<. -// This declaration will allow use to use CHECK macros for user -// defined classes which have operator<< (e.g., stl_logging.h). -inline std::ostream& operator<<( - std::ostream& out, const google::DummyClassToDefineOperator&) { - return out; -} - -@ac_google_start_namespace@ - -// This formats a value for a failing CHECK_XX statement. Ordinarily, -// it uses the definition for operator<<, with a few special cases below. -template <typename T> -inline void MakeCheckOpValueString(std::ostream* os, const T& v) { - (*os) << v; -} - -// Overrides for char types provide readable values for unprintable -// characters. -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const signed char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); - -// Build the error message string. Specify no inlining for code size. -template <typename T1, typename T2> -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) - @ac_cv___attribute___noinline@; - -namespace base { -namespace internal { - -// If "s" is less than base_logging::INFO, returns base_logging::INFO. -// If "s" is greater than base_logging::FATAL, returns -// base_logging::ERROR. Otherwise, returns "s". -LogSeverity NormalizeSeverity(LogSeverity s); - -} // namespace internal - -// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX -// statement. See MakeCheckOpString for sample usage. Other -// approaches were considered: use of a template method (e.g., -// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1, -// base::Print<T2>, &v2), however this approach has complications -// related to volatile arguments and function-pointer arguments). -class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { - public: - // Inserts "exprtext" and " (" to the stream. - explicit CheckOpMessageBuilder(const char *exprtext); - // Deletes "stream_". - ~CheckOpMessageBuilder(); - // For inserting the first variable. - std::ostream* ForVar1() { return stream_; } - // For inserting the second variable (adds an intermediate " vs. "). - std::ostream* ForVar2(); - // Get the result (inserts the closing ")"). - std::string* NewString(); - - private: - std::ostringstream *stream_; -}; - -} // namespace base - -template <typename T1, typename T2> -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { - base::CheckOpMessageBuilder comb(exprtext); - MakeCheckOpValueString(comb.ForVar1(), v1); - MakeCheckOpValueString(comb.ForVar2(), v2); - return comb.NewString(); -} - -// Helper functions for CHECK_OP macro. -// The (int, int) specialization works around the issue that the compiler -// will not instantiate the template version of the function on values of -// unnamed enum type - see comment below. -#define DEFINE_CHECK_OP_IMPL(name, op) \ - template <typename T1, typename T2> \ - inline std::string* name##Impl(const T1& v1, const T2& v2, \ - const char* exprtext) { \ - if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ - else return MakeCheckOpString(v1, v2, exprtext); \ - } \ - inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ - return name##Impl<int, int>(v1, v2, exprtext); \ - } - -// We use the full name Check_EQ, Check_NE, etc. in case the file including -// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. -// This happens if, for example, those are used as token names in a -// yacc grammar. -DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? -DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. -DEFINE_CHECK_OP_IMPL(Check_LE, <=) -DEFINE_CHECK_OP_IMPL(Check_LT, < ) -DEFINE_CHECK_OP_IMPL(Check_GE, >=) -DEFINE_CHECK_OP_IMPL(Check_GT, > ) -#undef DEFINE_CHECK_OP_IMPL - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. - -#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)) -#elif DCHECK_IS_ON() -// In debug mode, avoid constructing CheckOpStrings if possible, -// to reduce the overhead of CHECK statments by 2x. -// Real DCHECK-heavy tests have seen 1.5x speedups. - -// The meaning of "string" might be different between now and -// when this macro gets invoked (e.g., if someone is experimenting -// with other string implementations that get defined after this -// 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 (@ac_google_namespace@::_Check_string* _result = \ - @ac_google_namespace@::Check##name##Impl( \ - @ac_google_namespace@::GetReferenceableValue(val1), \ - @ac_google_namespace@::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, \ - @ac_google_namespace@::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 (@ac_google_namespace@::CheckOpString _result = \ - @ac_google_namespace@::Check##name##Impl( \ - @ac_google_namespace@::GetReferenceableValue(val1), \ - @ac_google_namespace@::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, @ac_google_namespace@::LogMessageFatal) -#else -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::NullStreamFatal) -#endif // STRIP_LOG <= 3 - -// Equality/Inequality checks - compare two values, and log a FATAL message -// including the two values when the result is not as expected. The values -// must have operator<<(ostream, ...) defined. -// -// You may append to the error message like so: -// CHECK_NE(1, 2) << ": The world must be ending!"; -// -// We are very careful to ensure that each argument is evaluated exactly -// once, and that anything which is legal to pass as a function argument is -// legal here. In particular, the arguments may be temporary expressions -// which will end up being destroyed at the end of the apparent statement, -// for example: -// CHECK_EQ(string("abc")[1], 'b'); -// -// WARNING: These don't compile correctly if one of the arguments is a pointer -// and the other is NULL. To work around this, simply static_cast NULL to the -// type of the desired pointer. - -#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) -#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) -#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) -#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) -#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) -#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) - -// Check that the input is non NULL. This very useful in constructor -// initializer lists. - -#define CHECK_NOTNULL(val) \ - @ac_google_namespace@::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) - -// Helper functions for string comparisons. -// To avoid bloat, the definitions are in logging.cc. -#define DECLARE_CHECK_STROP_IMPL(func, expected) \ - GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ - const char* s1, const char* s2, const char* names); -DECLARE_CHECK_STROP_IMPL(strcmp, true) -DECLARE_CHECK_STROP_IMPL(strcmp, false) -DECLARE_CHECK_STROP_IMPL(strcasecmp, true) -DECLARE_CHECK_STROP_IMPL(strcasecmp, false) -#undef DECLARE_CHECK_STROP_IMPL - -// Helper macro for string comparisons. -// Don't use this macro directly in your code, use CHECK_STREQ et al below. -#define CHECK_STROP(func, op, expected, s1, s2) \ - while (@ac_google_namespace@::CheckOpString _result = \ - @ac_google_namespace@::Check##func##expected##Impl((s1), (s2), \ - #s1 " " #op " " #s2)) \ - LOG(FATAL) << *_result.str_ - - -// String (char*) equality/inequality checks. -// CASE versions are case-insensitive. -// -// Note that "s1" and "s2" may be temporary strings which are destroyed -// by the compiler at the end of the current "full expression" -// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). - -#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) -#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) -#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) -#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) - -#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) -#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) - -#define CHECK_DOUBLE_EQ(val1, val2) \ - do { \ - CHECK_LE((val1), (val2)+0.000000000000001L); \ - CHECK_GE((val1), (val2)-0.000000000000001L); \ - } while (0) - -#define CHECK_NEAR(val1, val2, margin) \ - do { \ - CHECK_LE((val1), (val2)+(margin)); \ - CHECK_GE((val1), (val2)-(margin)); \ - } while (0) - -// perror()..googly style! -// -// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and -// CHECK equivalents with the addition that they postpend a description -// of the current state of errno to their output lines. - -#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() - -#define GOOGLE_PLOG(severity, counter) \ - @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) - -#define PLOG_IF(severity, condition) \ - static_cast<void>(0), \ - !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & PLOG(severity) - -// A CHECK() macro that postpends errno if the condition is false. E.g. -// -// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } -#define PCHECK(condition) \ - PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A CHECK() macro that lets you assert the success of a function that -// returns -1 and sets errno in case of an error. E.g. -// -// CHECK_ERR(mkdir(path, 0700)); -// -// or -// -// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; -#define CHECK_ERR(invocation) \ -PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ - << #invocation - -// Use macro expansion to create, for each use of LOG_EVERY_N(), static -// variables with the __LINE__ expansion as part of the variable name. -#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) -#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line - -#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) -#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) - -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (condition && \ - ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0; \ - if (LOG_OCCURRENCES <= n) \ - ++LOG_OCCURRENCES; \ - if (LOG_OCCURRENCES <= n) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -namespace glog_internal_namespace_ { -template <bool> -struct CompileAssert { -}; -struct CrashReason; - -// Returns true if FailureSignalHandler is installed. -// Needs to be exported since it's used by the signalhandler_unittest. -GOOGLE_GLOG_DLL_DECL bool IsFailureSignalHandlerInstalled(); -} // namespace glog_internal_namespace_ - -#define LOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) - -#define SYSLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToSyslogAndLog) - -#define PLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_PLOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) - -#define LOG_FIRST_N(severity, n) \ - SOME_KIND_OF_LOG_FIRST_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) - -#define LOG_IF_EVERY_N(severity, condition, n) \ - SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), @ac_google_namespace@::LogMessage::SendToLog) - -// We want the special COUNTER value available for LOG_EVERY_X()'ed messages -enum PRIVATE_Counter {COUNTER}; - -#ifdef GLOG_NO_ABBREVIATED_SEVERITIES -// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets -// 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 -// Needed for LOG_IS_ON(ERROR). -const LogSeverity GLOG_0 = GLOG_ERROR; -#else -// Users may include windows.h after logging.h without -// 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 -#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_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) - -#else // !DCHECK_IS_ON() - -#define DLOG(severity) \ - static_cast<void>(0), \ - true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DVLOG(verboselevel) \ - static_cast<void>(0), \ - (true || !VLOG_IS_ON(verboselevel)) ? \ - (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(INFO) - -#define DLOG_IF(severity, condition) \ - static_cast<void>(0), \ - (true || !(condition)) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DLOG_EVERY_N(severity, n) \ - static_cast<void>(0), \ - true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DLOG_IF_EVERY_N(severity, condition, n) \ - static_cast<void>(0), \ - (true || !(condition))? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#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_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_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_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) - -// 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_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_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) - -#endif // DCHECK_IS_ON() - -// Log only in verbose mode. - -#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) - -#define VLOG_IF(verboselevel, condition) \ - LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) - -#define VLOG_EVERY_N(verboselevel, n) \ - LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) - -#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ - LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) - -namespace base_logging { - -// LogMessage::LogStream is a std::ostream backed by this streambuf. -// This class ignores overflow and leaves two bytes at the end of the -// buffer to allow for a '\n' and '\0'. -class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf { - public: - // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\0'. - LogStreamBuf(char *buf, int len) { - setp(buf, buf + len - 2); - } - - // This effectively ignores overflow. - virtual int_type overflow(int_type ch) { - return ch; - } - - // Legacy public ostrstream method. - size_t pcount() const { return pptr() - pbase(); } - char* pbase() const { return std::streambuf::pbase(); } -}; - -} // namespace base_logging - -// -// This class more or less represents a particular log message. You -// create an instance of LogMessage and then stream stuff to it. -// When you finish streaming to it, ~LogMessage is called and the -// full message gets streamed to the appropriate destination. -// -// You shouldn't actually use LogMessage's constructor to log things, -// though. You should use the LOG() macro (and variants thereof) -// above. -class GOOGLE_GLOG_DLL_DECL LogMessage { -public: - enum { - // Passing kNoLogPrefix for the line number disables the - // log-message prefix. Useful for using the LogMessage - // infrastructure as a printing utility. See also the --log_prefix - // flag for controlling the log-message prefix on an - // application-wide basis. - kNoLogPrefix = -1 - }; - - // LogStream inherit from non-DLL-exported class (std::ostrstream) - // and VC++ produces a warning for this situation. - // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ - // 2005 if you are deriving from a type in the Standard C++ Library" - // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx - // Let's just ignore the warning. -GLOG_MSVC_PUSH_DISABLE_WARNING(4275) - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { -GLOG_MSVC_POP_WARNING() - public: - LogStream(char *buf, int len, int ctr) - : std::ostream(NULL), - streambuf_(buf, len), - ctr_(ctr), - self_(this) { - rdbuf(&streambuf_); - } - - int ctr() const { return ctr_; } - void set_ctr(int ctr) { ctr_ = ctr; } - LogStream* self() const { return self_; } - - // Legacy std::streambuf methods. - size_t pcount() const { return streambuf_.pcount(); } - char* pbase() const { return streambuf_.pbase(); } - char* str() const { return pbase(); } - - private: - LogStream(const LogStream&); - LogStream& operator=(const LogStream&); - base_logging::LogStreamBuf streambuf_; - int ctr_; // Counter hack (for the LOG_EVERY_X() macro) - LogStream *self_; // Consistency check hack - }; - -public: - // icc 8 requires this typedef to avoid an internal compiler error. - typedef void (LogMessage::*SendMethod)(); - - LogMessage(const char* file, int line, LogSeverity severity, int ctr, - SendMethod send_method); - - // Two special constructors that generate reduced amounts of code at - // LOG call sites for common cases. - - // Used for LOG(INFO): Implied are: - // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. - // - // Using this constructor instead of the more complex constructor above - // saves 19 bytes per call site. - LogMessage(const char* file, int line); - - // Used for LOG(severity) where severity != INFO. Implied - // are: ctr = 0, send_method = &LogMessage::SendToLog - // - // Using this constructor instead of the more complex constructor above - // saves 17 bytes per call site. - LogMessage(const char* file, int line, LogSeverity severity); - - // Constructor to log this message to a specified sink (if not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if - // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise. - LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink, - bool also_send_to_log); - - // Constructor where we also give a vector<string> pointer - // for storing the messages (if the pointer is not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::vector<std::string>* outvec); - - // Constructor where we also give a string pointer for storing the - // message (if the pointer is not NULL). Implied are: ctr = 0, - // send_method = &LogMessage::WriteToStringAndLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::string* message); - - // A special constructor used for check failures - LogMessage(const char* file, int line, const CheckOpString& result); - - ~LogMessage(); - - // Flush a buffered message to the sink set in the constructor. Always - // called by the destructor, it may also be called from elsewhere if - // needed. Only the first call is actioned; any later ones are ignored. - void Flush(); - - // An arbitrary limit on the length of a single log message. This - // is so that streaming can be done more efficiently. - static const size_t kMaxLogMessageLen; - - // Theses should not be called directly outside of logging.*, - // only passed as SendMethod arguments to other LogMessage methods: - void SendToLog(); // Actually dispatch to the logs - void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs - - // Call abort() or similar to perform LOG(FATAL) crash. - static void @ac_cv___attribute___noreturn@ Fail(); - - std::ostream& stream(); - - int preserved_errno() const; - - // Must be called without the log_mutex held. (L < log_mutex) - static int64 num_messages(int severity); - - struct LogMessageData; - -private: - // Fully internal SendMethod cases: - void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs - void SendToSink(); // Send to sink if provided, do nothing otherwise. - - // Write to string if provided and dispatch to the logs. - void WriteToStringAndLog(); - - void SaveOrSendToLog(); // Save to stringvec if provided, else to logs - - void Init(const char* file, int line, LogSeverity severity, - void (LogMessage::*send_method)()); - - // Used to fill in crash information during LOG(FATAL) failures. - void RecordCrashReason(glog_internal_namespace_::CrashReason* reason); - - // Counts of messages sent at each priority: - static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex - - // We keep the data in a separate struct so that each instance of - // LogMessage uses less stack space. - LogMessageData* allocated_; - LogMessageData* data_; - - friend class LogDestination; - - LogMessage(const LogMessage&); - void operator=(const LogMessage&); -}; - -// This class happens to be thread-hostile because all instances share -// a single data buffer, but since it can only be created just before -// the process dies, we don't worry so much. -class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { - public: - LogMessageFatal(const char* file, int line); - LogMessageFatal(const char* file, int line, const CheckOpString& result); - @ac_cv___attribute___noreturn@ ~LogMessageFatal(); -}; - -// A non-macro interface to the log facility; (useful -// when the logging level is not a compile-time constant). -inline void LogAtLevel(int const severity, std::string const &msg) { - LogMessage(__FILE__, __LINE__, severity).stream() << msg; -} - -// A macro alternative of LogAtLevel. New code may want to use this -// version since there are two advantages: 1. this version outputs the -// file name and the line number where this macro is put like other -// LOG macros, 2. this macro can be used as C++ stream. -#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream() - -// Check if it's compiled in C++11 mode. -// -// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least -// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1 -// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is -// defined according to the language version in effect thereafter. -// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite -// reasonably good C++11 support, so we set LANG_CXX for it and -// newer versions (_MSC_VER >= 1900). -#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ - (defined(_MSC_VER) && _MSC_VER >= 1900)) && !defined(__UCLIBCXX_MAJOR__) -// Helper for CHECK_NOTNULL(). -// -// In C++11, all cases can be handled by a single function. Since the value -// category of the argument is preserved (also for rvalue references), -// member initializer lists like the one below will compile correctly: -// -// Foo() -// : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {} -template <typename T> -T CheckNotNull(const char* file, int line, const char* names, T&& t) { - if (t == nullptr) { - LogMessageFatal(file, line, new std::string(names)); - } - return std::forward<T>(t); -} - -#else - -// A small helper for CHECK_NOTNULL(). -template <typename T> -T* CheckNotNull(const char *file, int line, const char *names, T* t) { - if (t == NULL) { - LogMessageFatal(file, line, new std::string(names)); - } - return t; -} -#endif - -// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This -// only works if ostream is a LogStream. If the ostream is not a -// LogStream you'll get an assert saying as much at runtime. -GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, - const PRIVATE_Counter&); - - -// Derived class for PLOG*() above. -class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { - public: - - ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, - void (LogMessage::*send_method)()); - - // Postpends ": strerror(errno) [errno]". - ~ErrnoLogMessage(); - - private: - ErrnoLogMessage(const ErrnoLogMessage&); - void operator=(const ErrnoLogMessage&); -}; - - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". - -class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-safe. -GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-hostile because it ignores -// locking -- used for catastrophic failures. -GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); - -// -// Set the destination to which a particular severity level of log -// messages is sent. If base_filename is "", it means "don't log this -// severity". Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, - const char* base_filename); - -// -// Set the basename of the symlink to the latest log file at a given -// severity. If symlink_basename is empty, do not make a symlink. If -// you don't call this function, the symlink basename is the -// invocation name of the program. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - -// -// Used to send logs to some other kind of destination -// Users should subclass LogSink and override send to do whatever they want. -// Implementations must be thread-safe because a shared instance will -// be called from whichever thread ran the LOG(XXX) line. -class GOOGLE_GLOG_DLL_DECL LogSink { - public: - virtual ~LogSink(); - - // Sink's logging logic (message_len is such as to exclude '\n' at the end). - // This method can't use LOG() or CHECK() as logging system mutex(s) are held - // during this call. - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len, int32 usecs) { - send(severity, full_filename, base_filename, line, - tm_time, message, message_len); - } - // This send() signature is obsolete. - // New implementations should define this in terms of - // the above send() method. - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) = 0; - - // Redefine this to implement waiting for - // the sink's logging logic to complete. - // It will be called after each send() returns, - // but before that LogMessage exits or crashes. - // By default this function does nothing. - // Using this function one can implement complex logic for send() - // that itself involves logging; and do all this w/o causing deadlocks and - // inconsistent rearrangement of log messages. - // E.g. if a LogSink has thread-specific actions, the send() method - // can simply add the message to a queue and wake up another thread that - // handles real logging while itself making some LOG() calls; - // WaitTillSent() can be implemented to wait for that logic to complete. - // See our unittest for an example. - virtual void WaitTillSent(); - - // Returns the normal text output of the log message. - // Can be useful to implement send(). - static std::string ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len, - int32 usecs); - - // Obsolete - static std::string ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) { - return ToString(severity, file, line, tm_time, message, message_len, 0); - } -}; - -// Add or remove a LogSink as a consumer of logging data. Thread-safe. -GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); -GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); - -// -// Specify an "extension" added to the filename specified via -// SetLogDestination. This applies to all severity levels. It's -// often used to append the port we're listening on to the logfile -// name. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( - const char* filename_extension); - -// -// Make it so that all log messages of at least a particular severity -// are logged to stderr (in addition to logging to the usual log -// file(s)). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); - -// -// Make it so that all log messages go only to stderr. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void LogToStderr(); - -// -// Make it so that all log messages of at least a particular severity are -// logged via email to a list of addresses (in addition to logging to the -// usual log file(s)). The list of addresses is just a string containing -// the email addresses to send to (separated by spaces, say). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, - const char* addresses); - -// A simple function that sends email. dest is a commma-separated -// list of addressess. Thread-safe. -GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, - const char *subject, const char *body); - -GOOGLE_GLOG_DLL_DECL const std::vector<std::string>& GetLoggingDirectories(); - -// For tests only: Clear the internal [cached] list of logging directories to -// force a refresh the next time GetLoggingDirectories is called. -// Thread-hostile. -void TestOnly_ClearLoggingDirectoriesList(); - -// Returns a set of existing temporary directories, which will be a -// subset of the directories returned by GetLogginDirectories(). -// Thread-safe. -GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( - std::vector<std::string>* list); - -// Print any fatal message again -- useful to call from signal handler -// so that the last thing in the output is the fatal message. -// Thread-hostile, but a race is unlikely. -GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); - -// Truncate a log file that may be the append-only output of multiple -// processes and hence can't simply be renamed/reopened (typically a -// stdout/stderr). If the file "path" is > "limit" bytes, copy the -// last "keep" bytes to offset 0 and truncate the rest. Since we could -// be racing with other writers, this approach has the potential to -// lose very small amounts of data. For security, only follow symlinks -// if the path is /proc/self/fd/* -GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, - int64 limit, int64 keep); - -// Truncate stdout and stderr if they are over the value specified by -// --max_log_size; keep the final 1MB. This function has the same -// race condition as TruncateLogFile. -GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); - -// Return the string representation of the provided LogSeverity level. -// Thread-safe. -GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); - -// --------------------------------------------------------------------- -// Implementation details that are not useful to most clients -// --------------------------------------------------------------------- - -// A Logger is the interface used by logging modules to emit entries -// to a log. A typical implementation will dump formatted data to a -// sequence of files. We also provide interfaces that will forward -// the data to another thread so that the invoker never blocks. -// Implementations should be thread-safe since the logging system -// will write to them from multiple threads. - -namespace base { - -class GOOGLE_GLOG_DLL_DECL Logger { - public: - virtual ~Logger(); - - // Writes "message[0,message_len-1]" corresponding to an event that - // occurred at "timestamp". If "force_flush" is true, the log file - // is flushed immediately. - // - // The input message has already been formatted as deemed - // appropriate by the higher level logging facility. For example, - // textual log messages already contain timestamps, and the - // file:linenumber header. - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) = 0; - - // Flush any buffered messages - virtual void Flush() = 0; - - // Get the current LOG file size. - // The returned value is approximate since some - // logged data may not have been flushed to disk yet. - virtual uint32 LogSize() = 0; -}; - -// Get the logger for the specified severity level. The logger -// remains the property of the logging module and should not be -// deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); - -// Set the logger for the specified severity level. The logger -// becomes the property of the logging module and should not -// be deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); - -} - -// glibc has traditionally implemented two incompatible versions of -// strerror_r(). There is a poorly defined convention for picking the -// version that we want, but it is not clear whether it even works with -// all versions of glibc. -// So, instead, we provide this wrapper that automatically detects the -// version that is in use, and then implements POSIX semantics. -// N.B. In addition to what POSIX says, we also guarantee that "buf" will -// be set to an empty string, if this function failed. This means, in most -// cases, you do not need to check the error code and you can directly -// use the value of "buf". It will never have an undefined value. -// DEPRECATED: Use StrError(int) instead. -GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); - -// A thread-safe replacement for strerror(). Returns a string describing the -// given POSIX error code. -GOOGLE_GLOG_DLL_DECL std::string StrError(int err); - -// A class for which we define operator<<, which does nothing. -class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { - public: - // Initialize the LogStream so the messages can be written somewhere - // (they'll never be actually displayed). This will be needed if a - // NullStream& is implicitly converted to LogStream&, in which case - // the overloaded NullStream::operator<< will not be invoked. - NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream(const char* /*file*/, int /*line*/, - const CheckOpString& /*result*/) : - LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream &stream() { return *this; } - private: - // A very short buffer for messages (which we discard anyway). This - // will be needed if NullStream& converted to LogStream& (e.g. as a - // result of a conditional expression). - char message_buffer_[2]; -}; - -// Do nothing. This operator is inline, allowing the message to be -// compiled away. The message will not be compiled away if we do -// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when -// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly -// converted to LogStream and the message will be computed and then -// quietly discarded. -template<class T> -inline NullStream& operator<<(NullStream &str, const T &) { return str; } - -// Similar to NullStream, but aborts the program (without stack -// trace), like LogMessageFatal. -class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { - public: - NullStreamFatal() { } - NullStreamFatal(const char* file, int line, const CheckOpString& result) : - NullStream(file, line, result) { } - @ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(1); } -}; - -// Install a signal handler that will dump signal information and a stack -// trace when the program crashes on certain signals. We'll install the -// signal handler for the following signals. -// -// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. -// -// By default, the signal handler will write the failure dump to the -// standard error. You can customize the destination by installing your -// own writer function by InstallFailureWriter() below. -// -// Note on threading: -// -// The function should be called before threads are created, if you want -// to use the failure signal handler for all threads. The stack trace -// will be shown only for the thread that receives the signal. In other -// words, stack traces of other threads won't be shown. -GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); - -// Installs a function that is used for writing the failure dump. "data" -// is the pointer to the beginning of a message to be written, and "size" -// is the size of the message. You should not expect the data is -// terminated with '\0'. -GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( - void (*writer)(const char* data, int size)); - -@ac_google_end_namespace@ - -#endif // _LOGGING_H_ diff --git a/third_party/glog/src/glog/raw_logging.h.in b/third_party/glog/src/glog/raw_logging.h.in deleted file mode 100644 index 31b7ed32d9a7..000000000000 --- a/third_party/glog/src/glog/raw_logging.h.in +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Maxim Lifantsev -// -// Thread-safe logging routines that do not allocate any memory or -// acquire any locks, and can therefore be used by low-level memory -// allocation and synchronization code. - -#ifndef BASE_RAW_LOGGING_H_ -#define BASE_RAW_LOGGING_H_ - -#include <time.h> - -@ac_google_start_namespace@ - -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// This is similar to LOG(severity) << format... and VLOG(level) << format.., -// but -// * it is to be used ONLY by low-level modules that can't use normal LOG() -// * it is desiged to be a low-level logger that does not allocate any -// memory and does not need any locks, hence: -// * it logs straight and ONLY to STDERR w/o buffering -// * it uses an explicit format and arguments list -// * it will silently chop off really long message strings -// Usage example: -// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); -// RAW_VLOG(3, "status is %i", status); -// These will print an almost standard log lines like this to stderr only: -// E20200821 211317 file.cc:123] RAW: Failed foo with 22: bad_file -// I20200821 211317 file.cc:142] RAW: status is 20 -#define RAW_LOG(severity, ...) \ - do { \ - switch (@ac_google_namespace@::GLOG_ ## severity) { \ - case 0: \ - RAW_LOG_INFO(__VA_ARGS__); \ - break; \ - case 1: \ - RAW_LOG_WARNING(__VA_ARGS__); \ - break; \ - case 2: \ - RAW_LOG_ERROR(__VA_ARGS__); \ - break; \ - case 3: \ - RAW_LOG_FATAL(__VA_ARGS__); \ - break; \ - default: \ - break; \ - } \ - } while (0) - -// The following STRIP_LOG testing is performed in the header file so that it's -// possible to completely compile out the logging code and the log messages. -#if STRIP_LOG == 0 -#define RAW_VLOG(verboselevel, ...) \ - do { \ - if (VLOG_IS_ON(verboselevel)) { \ - RAW_LOG_INFO(__VA_ARGS__); \ - } \ - } while (0) -#else -#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG == 0 -#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_INFO, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG <= 1 -#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_WARNING, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 1 - -#if STRIP_LOG <= 2 -#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_ERROR, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 2 - -#if STRIP_LOG <= 3 -#define RAW_LOG_FATAL(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_FATAL, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_FATAL(...) \ - do { \ - @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__); \ - exit(1); \ - } while (0) -#endif // STRIP_LOG <= 3 - -// Similar to CHECK(condition) << message, -// but for low-level modules: we use only RAW_LOG that does not allocate memory. -// We do not want to provide args list here to encourage this usage: -// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); -// so that the args are not computed when not needed. -#define RAW_CHECK(condition, message) \ - do { \ - if (!(condition)) { \ - RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ - } \ - } while (0) - -// Debug versions of RAW_LOG and RAW_CHECK -#ifndef NDEBUG - -#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) - -#else // NDEBUG - -#define RAW_DLOG(severity, ...) \ - while (false) \ - RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) \ - while (false) \ - RAW_CHECK(condition, message) - -#endif // NDEBUG - -// Stub log function used to work around for unused variable warnings when -// building with STRIP_LOG > 0. -static inline void RawLogStub__(int /* ignored */, ...) { -} - -// Helper function to implement RAW_LOG and RAW_VLOG -// Logs format... at "severity" level, reporting it -// as called from file:line. -// This does not allocate memory or acquire locks. -GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, - const char* file, - int line, - const char* format, ...) - @ac_cv___attribute___printf_4_5@; - -@ac_google_end_namespace@ - -#endif // BASE_RAW_LOGGING_H_ diff --git a/third_party/glog/src/glog/stl_logging.h.in b/third_party/glog/src/glog/stl_logging.h.in deleted file mode 100644 index 600945d2c22f..000000000000 --- a/third_party/glog/src/glog/stl_logging.h.in +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) 2003, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Stream output operators for STL containers; to be used for logging *only*. -// Inclusion of this file lets you do: -// -// list<string> x; -// LOG(INFO) << "data: " << x; -// vector<int> v1, v2; -// CHECK_EQ(v1, v2); -// -// If you want to use this header file with hash maps or slist, you -// need to define macros before including this file: -// -// - GLOG_STL_LOGGING_FOR_UNORDERED - <unordered_map> and <unordered_set> -// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)> -// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)> -// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <ext/slist> -// - -#ifndef UTIL_GTL_STL_LOGGING_INL_H_ -#define UTIL_GTL_STL_LOGGING_INL_H_ - -#if !@ac_cv_cxx_using_operator@ -# error We do not support stl_logging for this compiler -#endif - -#include <deque> -#include <list> -#include <map> -#include <ostream> -#include <set> -#include <utility> -#include <vector> - -#ifdef GLOG_STL_LOGGING_FOR_UNORDERED -# include <unordered_map> -# include <unordered_set> -#endif - -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# include <tr1/unordered_map> -# include <tr1/unordered_set> -#endif - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -# include <ext/hash_set> -# include <ext/hash_map> -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST -# include <ext/slist> -#endif - -// Forward declare these two, and define them after all the container streams -// operators so that we can recurse from pair -> container -> container -> pair -// properly. -template<class First, class Second> -std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p); - -@ac_google_start_namespace@ - -template<class Iter> -void PrintSequence(std::ostream& out, Iter begin, Iter end); - -@ac_google_end_namespace@ - -#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ -template<class T1, class T2> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2>& seq) { \ - @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_TWO_ARG_CONTAINER(std::vector) -OUTPUT_TWO_ARG_CONTAINER(std::deque) -OUTPUT_TWO_ARG_CONTAINER(std::list) -#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST -OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist) -#endif - -#undef OUTPUT_TWO_ARG_CONTAINER - -#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \ -template<class T1, class T2, class T3> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2, T3>& seq) { \ - @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_THREE_ARG_CONTAINER(std::set) -OUTPUT_THREE_ARG_CONTAINER(std::multiset) - -#undef OUTPUT_THREE_ARG_CONTAINER - -#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \ -template<class T1, class T2, class T3, class T4> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2, T3, T4>& seq) { \ - @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_FOUR_ARG_CONTAINER(std::map) -OUTPUT_FOUR_ARG_CONTAINER(std::multimap) -#ifdef GLOG_STL_LOGGING_FOR_UNORDERED -OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set) -OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset) -#endif -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set) -OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset) -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set) -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset) -#endif - -#undef OUTPUT_FOUR_ARG_CONTAINER - -#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \ -template<class T1, class T2, class T3, class T4, class T5> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2, T3, T4, T5>& seq) { \ - @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -#ifdef GLOG_STL_LOGGING_FOR_UNORDERED -OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map) -OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap) -#endif -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map) -OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap) -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map) -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap) -#endif - -#undef OUTPUT_FIVE_ARG_CONTAINER - -template<class First, class Second> -inline std::ostream& operator<<(std::ostream& out, - const std::pair<First, Second>& p) { - out << '(' << p.first << ", " << p.second << ')'; - return out; -} - -@ac_google_start_namespace@ - -template<class Iter> -inline void PrintSequence(std::ostream& out, Iter begin, Iter end) { - // Output at most 100 elements -- appropriate if used for logging. - for (int i = 0; begin != end && i < 100; ++i, ++begin) { - if (i > 0) out << ' '; - out << *begin; - } - if (begin != end) { - out << " ..."; - } -} - -@ac_google_end_namespace@ - -// Note that this is technically undefined behavior! We are adding things into -// the std namespace for a reason though -- we are providing new operations on -// types which are themselves defined with this namespace. Without this, these -// operator overloads cannot be found via ADL. If these definitions are not -// found via ADL, they must be #included before they're used, which requires -// this header to be included before apparently independent other headers. -// -// For example, base/logging.h defines various template functions to implement -// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails. -// It does so via the function template MakeCheckOpValueString: -// template<class T> -// void MakeCheckOpValueString(strstream* ss, const T& v) { -// (*ss) << v; -// } -// Because 'glog/logging.h' is included before 'glog/stl_logging.h', -// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only -// find these operator definitions via ADL. -// -// Even this solution has problems -- it may pull unintended operators into the -// namespace as well, allowing them to also be found via ADL, and creating code -// that only works with a particular order of includes. Long term, we need to -// move all of the *definitions* into namespace std, bet we need to ensure no -// one references them first. This lets us take that step. We cannot define them -// in both because that would create ambiguous overloads when both are found. -namespace std { using ::operator<<; } - -#endif // UTIL_GTL_STL_LOGGING_INL_H_ diff --git a/third_party/glog/src/glog/vlog_is_on.h.in b/third_party/glog/src/glog/vlog_is_on.h.in deleted file mode 100644 index 3f4c4a32a8b7..000000000000 --- a/third_party/glog/src/glog/vlog_is_on.h.in +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 1999, 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Ray Sidney and many others -// -// Defines the VLOG_IS_ON macro that controls the variable-verbosity -// conditional logging. -// -// It's used by VLOG and VLOG_IF in logging.h -// and by RAW_VLOG in raw_logging.h to trigger the logging. -// -// It can also be used directly e.g. like this: -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished e.g. via just VLOG(2) << ...; -// } -// -// The truth value that VLOG_IS_ON(level) returns is determined by -// the three verbosity level flags: -// --v=<n> Gives the default maximal active V-logging level; -// 0 is the default. -// Normally positive values are used for V-logging levels. -// --vmodule=<str> Gives the per-module maximal V-logging levels to override -// the value given by --v. -// E.g. "my_module=2,foo*=3" would change the logging level -// for all code in source files "my_module.*" and "foo*.*" -// ("-inl" suffixes are also disregarded for this matching). -// -// SetVLOGLevel helper function is provided to do limited dynamic control over -// V-logging by overriding the per-module settings given via --vmodule flag. -// -// CAVEAT: --vmodule functionality is not available in non gcc compilers. -// - -#ifndef BASE_VLOG_IS_ON_H_ -#define BASE_VLOG_IS_ON_H_ - -#include "glog/log_severity.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -#if defined(__GNUC__) -// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. -// (Normally) the first time every VLOG_IS_ON(n) site is hit, -// we determine what variable will dynamically control logging at this site: -// it's either FLAGS_v or an appropriate internal variable -// matching the current source file that represents results of -// parsing of --vmodule flag and/or SetVLOGLevel calls. -#define VLOG_IS_ON(verboselevel) \ - __extension__ \ - ({ static @ac_google_namespace@::int32* vlocal__ = &@ac_google_namespace@::kLogSiteUninitialized; \ - @ac_google_namespace@::int32 verbose_level__ = (verboselevel); \ - (*vlocal__ >= verbose_level__) && \ - ((vlocal__ != &@ac_google_namespace@::kLogSiteUninitialized) || \ - (@ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \ - __FILE__, verbose_level__))); }) -#else -// GNU extensions not available, so we do not support --vmodule. -// Dynamic value of FLAGS_v always controls the logging level. -#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) -#endif - -// Set VLOG(_IS_ON) level for module_pattern to log_level. -// This lets us dynamically control what is normally set by the --vmodule flag. -// Returns the level that previously applied to module_pattern. -// NOTE: To change the log level for VLOG(_IS_ON) sites -// that have already executed after/during InitGoogleLogging, -// one needs to supply the exact --vmodule pattern that applied to them. -// (If no --vmodule pattern applied to them -// the value of FLAGS_v will continue to control them.) -extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, - int log_level); - -// Various declarations needed for VLOG_IS_ON above: ========================= - -// Special value used to indicate that a VLOG_IS_ON site has not been -// initialized. We make this a large value, so the common-case check -// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition -// passes in such cases and InitVLOG3__ is then triggered. -extern @ac_google_namespace@::int32 kLogSiteUninitialized; - -// Helper routine which determines the logging info for a particalur VLOG site. -// site_flag is the address of the site-local pointer to the controlling -// verbosity level -// site_default is the default to use for *site_flag -// fname is the current source file name -// verbose_level is the argument to VLOG_IS_ON -// We will return the return value for VLOG_IS_ON -// and if possible set *site_flag appropriately. -extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( - @ac_google_namespace@::int32** site_flag, - @ac_google_namespace@::int32* site_default, - const char* fname, - @ac_google_namespace@::int32 verbose_level); - -#endif // BASE_VLOG_IS_ON_H_ diff --git a/third_party/glog/src/googletest.h b/third_party/glog/src/googletest.h deleted file mode 100644 index a9e7795dcae1..000000000000 --- a/third_party/glog/src/googletest.h +++ /dev/null @@ -1,611 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Shinichiro Hamaji -// (based on googletest: http://code.google.com/p/googletest/) - -#ifdef GOOGLETEST_H__ -#error You must not include this file twice. -#endif -#define GOOGLETEST_H__ - -#include "utilities.h" - -#include <ctype.h> -#include <setjmp.h> -#include <time.h> - -#include <map> -#include <sstream> -#include <string> -#include <vector> - -#include <stdio.h> -#include <stdlib.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -#include "base/commandlineflags.h" - -using std::map; -using std::string; -using std::vector; - -_START_GOOGLE_NAMESPACE_ - -extern GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)(); - -_END_GOOGLE_NAMESPACE_ - -#undef GOOGLE_GLOG_DLL_DECL -#define GOOGLE_GLOG_DLL_DECL - -static inline string GetTempDir() { -#ifndef OS_WINDOWS - return "/tmp"; -#else - char tmp[MAX_PATH]; - GetTempPathA(MAX_PATH, tmp); - return tmp; -#endif -} - -#if defined(OS_WINDOWS) && defined(_MSC_VER) && !defined(TEST_SRC_DIR) -// The test will run in glog/vsproject/<project name> -// (e.g., glog/vsproject/logging_unittest). -static const char TEST_SRC_DIR[] = "../.."; -#elif !defined(TEST_SRC_DIR) -# warning TEST_SRC_DIR should be defined in config.h -static const char TEST_SRC_DIR[] = "."; -#endif - -static const uint32_t PTR_TEST_VALUE = 0x12345678; - -DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files"); -DEFINE_string(test_srcdir, TEST_SRC_DIR, - "Source-dir root, needed to find glog_unittest_flagfile"); -DEFINE_bool(run_benchmark, false, "If true, run benchmarks"); -#ifdef NDEBUG -DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark"); -#else -DEFINE_int32(benchmark_iters, 100000, "Number of iterations per benchmark"); -#endif - -#ifdef HAVE_LIB_GTEST -# include <gtest/gtest.h> -// Use our ASSERT_DEATH implementation. -# undef ASSERT_DEATH -# undef ASSERT_DEBUG_DEATH -using testing::InitGoogleTest; -#else - -_START_GOOGLE_NAMESPACE_ - -void InitGoogleTest(int*, char**); - -void InitGoogleTest(int*, char**) {} - -// The following is some bare-bones testing infrastructure - -#define EXPECT_TRUE(cond) \ - do { \ - if (!(cond)) { \ - fprintf(stderr, "Check failed: %s\n", #cond); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_FALSE(cond) EXPECT_TRUE(!(cond)) - -#define EXPECT_OP(op, val1, val2) \ - do { \ - if (!((val1) op (val2))) { \ - fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2) -#define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2) -#define EXPECT_GT(val1, val2) EXPECT_OP(>, val1, val2) -#define EXPECT_LT(val1, val2) EXPECT_OP(<, val1, val2) - -#define EXPECT_NAN(arg) \ - do { \ - if (!isnan(arg)) { \ - fprintf(stderr, "Check failed: isnan(%s)\n", #arg); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_INF(arg) \ - do { \ - if (!isinf(arg)) { \ - fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \ - exit(1); \ - } \ - } 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(1); \ - } \ - } while (0) - -#define EXPECT_STREQ(val1, val2) \ - do { \ - if (strcmp((val1), (val2)) != 0) { \ - fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \ - exit(1); \ - } \ - } while (0) - -vector<void (*)()> g_testlist; // the tests to run - -#define TEST(a, b) \ - struct Test_##a##_##b { \ - Test_##a##_##b() { g_testlist.push_back(&Run); } \ - static void Run() { FlagSaver fs; RunTest(); } \ - static void RunTest(); \ - }; \ - static Test_##a##_##b g_test_##a##_##b; \ - void Test_##a##_##b::RunTest() - - -static inline int RUN_ALL_TESTS() { - vector<void (*)()>::const_iterator it; - for (it = g_testlist.begin(); it != g_testlist.end(); ++it) { - (*it)(); - } - fprintf(stderr, "Passed %d tests\n\nPASS\n", (int)g_testlist.size()); - return 0; -} - -_END_GOOGLE_NAMESPACE_ - -#endif // ! HAVE_LIB_GTEST - -_START_GOOGLE_NAMESPACE_ - -static bool g_called_abort; -static jmp_buf g_jmp_buf; -static inline void CalledAbort() { - g_called_abort = true; - longjmp(g_jmp_buf, 1); -} - -#ifdef OS_WINDOWS -// TODO(hamaji): Death test somehow doesn't work in Windows. -#define ASSERT_DEATH(fn, msg) -#else -#define ASSERT_DEATH(fn, msg) \ - do { \ - g_called_abort = false; \ - /* in logging.cc */ \ - void (*original_logging_fail_func)() = g_logging_fail_func; \ - g_logging_fail_func = &CalledAbort; \ - if (!setjmp(g_jmp_buf)) fn; \ - /* set back to their default */ \ - g_logging_fail_func = original_logging_fail_func; \ - if (!g_called_abort) { \ - fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn); \ - exit(1); \ - } \ - } while (0) -#endif - -#ifdef NDEBUG -#define ASSERT_DEBUG_DEATH(fn, msg) -#else -#define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg) -#endif // NDEBUG - -// Benchmark tools. - -#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n); - -map<string, void (*)(int)> g_benchlist; // the benchmarks to run - -class BenchmarkRegisterer { - public: - BenchmarkRegisterer(const char* name, void (*function)(int iters)) { - EXPECT_TRUE(g_benchlist.insert(std::make_pair(name, function)).second); - } -}; - -static inline void RunSpecifiedBenchmarks() { - if (!FLAGS_run_benchmark) { - return; - } - - int iter_cnt = FLAGS_benchmark_iters; - puts("Benchmark\tTime(ns)\tIterations"); - for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin(); - iter != g_benchlist.end(); - ++iter) { - clock_t start = clock(); - iter->second(iter_cnt); - double elapsed_ns = - ((double)clock() - start) / CLOCKS_PER_SEC * 1000*1000*1000; - printf("%s\t%8.2lf\t%10d\n", - iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt); - } - puts(""); -} - -// ---------------------------------------------------------------------- -// Golden file functions -// ---------------------------------------------------------------------- - -class CapturedStream { - public: - CapturedStream(int fd, const string & filename) : - fd_(fd), - uncaptured_fd_(-1), - filename_(filename) { - Capture(); - } - - ~CapturedStream() { - if (uncaptured_fd_ != -1) { - CHECK(close(uncaptured_fd_) != -1); - } - } - - // Start redirecting output to a file - void Capture() { - // Keep original stream for later - CHECK(uncaptured_fd_ == -1) << ", Stream " << fd_ << " already captured!"; - uncaptured_fd_ = dup(fd_); - CHECK(uncaptured_fd_ != -1); - - // Open file to save stream to - int cap_fd = open(filename_.c_str(), - O_CREAT | O_TRUNC | O_WRONLY, - S_IRUSR | S_IWUSR); - CHECK(cap_fd != -1); - - // Send stdout/stderr to this file - fflush(NULL); - CHECK(dup2(cap_fd, fd_) != -1); - CHECK(close(cap_fd) != -1); - } - - // Remove output redirection - void StopCapture() { - // Restore original stream - if (uncaptured_fd_ != -1) { - fflush(NULL); - CHECK(dup2(uncaptured_fd_, fd_) != -1); - } - } - - const string & filename() const { return filename_; } - - private: - int fd_; // file descriptor being captured - int uncaptured_fd_; // where the stream was originally being sent to - string filename_; // file where stream is being saved -}; -static CapturedStream * s_captured_streams[STDERR_FILENO+1]; -// Redirect a file descriptor to a file. -// fd - Should be STDOUT_FILENO or STDERR_FILENO -// filename - File where output should be stored -static inline void CaptureTestOutput(int fd, const string & filename) { - CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO)); - CHECK(s_captured_streams[fd] == NULL); - s_captured_streams[fd] = new CapturedStream(fd, filename); -} -static inline void CaptureTestStderr() { - CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err"); -} -// Return the size (in bytes) of a file -static inline size_t GetFileSize(FILE * file) { - fseek(file, 0, SEEK_END); - return static_cast<size_t>(ftell(file)); -} -// Read the entire content of a file as a string -static inline string ReadEntireFile(FILE * file) { - const size_t file_size = GetFileSize(file); - char * const buffer = new char[file_size]; - - size_t bytes_last_read = 0; // # of bytes read in the last fread() - size_t bytes_read = 0; // # of bytes read so far - - fseek(file, 0, SEEK_SET); - - // Keep reading the file until we cannot read further or the - // pre-determined file size is reached. - do { - bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); - bytes_read += bytes_last_read; - } while (bytes_last_read > 0 && bytes_read < file_size); - - const string content = string(buffer, buffer+bytes_read); - delete[] buffer; - - return content; -} -// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when -// fd is STDERR_FILENO) as a string -static inline string GetCapturedTestOutput(int fd) { - CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO); - CapturedStream * const cap = s_captured_streams[fd]; - CHECK(cap) - << ": did you forget CaptureTestStdout() or CaptureTestStderr()?"; - - // Make sure everything is flushed. - cap->StopCapture(); - - // Read the captured file. - FILE * const file = fopen(cap->filename().c_str(), "r"); - const string content = ReadEntireFile(file); - fclose(file); - - delete cap; - s_captured_streams[fd] = NULL; - - return content; -} -// Get the captured stderr of a test as a string. -static inline string GetCapturedTestStderr() { - return GetCapturedTestOutput(STDERR_FILENO); -} - -// Check if the string is [IWEF](\d{8}|YEARDATE) -static inline bool IsLoggingPrefix(const string& s) { - if (s.size() != 9) return false; - if (!strchr("IWEF", s[0])) return false; - for (int i = 1; i <= 8; ++i) { - if (!isdigit(s[i]) && s[i] != "YEARDATE"[i-1]) return false; - } - return true; -} - -// Convert log output into normalized form. -// -// Example: -// I20200102 030405 logging_unittest.cc:345] RAW: vlog -1 -// => IYEARDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1 -static inline string MungeLine(const string& line) { - std::istringstream iss(line); - string before, logcode_date, time, thread_lineinfo; - iss >> logcode_date; - while (!IsLoggingPrefix(logcode_date)) { - before += " " + logcode_date; - if (!(iss >> logcode_date)) { - // We cannot find the header of log output. - return before; - } - } - if (!before.empty()) before += " "; - iss >> time; - iss >> thread_lineinfo; - CHECK(!thread_lineinfo.empty()); - if (thread_lineinfo[thread_lineinfo.size() - 1] != ']') { - // We found thread ID. - string tmp; - iss >> tmp; - CHECK(!tmp.empty()); - CHECK_EQ(']', tmp[tmp.size() - 1]); - thread_lineinfo = "THREADID " + tmp; - } - size_t index = thread_lineinfo.find(':'); - CHECK_NE(string::npos, index); - thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]"; - string rest; - std::getline(iss, rest); - return (before + logcode_date[0] + "YEARDATE TIME__ " + thread_lineinfo + - MungeLine(rest)); -} - -static inline void StringReplace(string* str, - const string& oldsub, - const string& newsub) { - size_t pos = str->find(oldsub); - if (pos != string::npos) { - str->replace(pos, oldsub.size(), newsub.c_str()); - } -} - -static inline string Munge(const string& filename) { - FILE* fp = fopen(filename.c_str(), "rb"); - CHECK(fp != NULL) << filename << ": couldn't open"; - char buf[4096]; - string result; - while (fgets(buf, 4095, fp)) { - string line = MungeLine(buf); - char null_str[256]; - char ptr_str[256]; - sprintf(null_str, "%p", static_cast<void*>(NULL)); - sprintf(ptr_str, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE)); - - StringReplace(&line, "__NULLP__", null_str); - StringReplace(&line, "__PTRTEST__", ptr_str); - - StringReplace(&line, "__SUCCESS__", StrError(0)); - StringReplace(&line, "__ENOENT__", StrError(ENOENT)); - StringReplace(&line, "__EINTR__", StrError(EINTR)); - StringReplace(&line, "__ENXIO__", StrError(ENXIO)); - StringReplace(&line, "__ENOEXEC__", StrError(ENOEXEC)); - result += line + "\n"; - } - fclose(fp); - return result; -} - -static inline void WriteToFile(const string& body, const string& file) { - FILE* fp = fopen(file.c_str(), "wb"); - fwrite(body.data(), 1, body.size(), fp); - fclose(fp); -} - -static inline bool MungeAndDiffTestStderr(const string& golden_filename) { - CapturedStream* cap = s_captured_streams[STDERR_FILENO]; - CHECK(cap) << ": did you forget CaptureTestStderr()?"; - - cap->StopCapture(); - - // Run munge - const string captured = Munge(cap->filename()); - const string golden = Munge(golden_filename); - if (captured != golden) { - fprintf(stderr, - "Test with golden file failed. We'll try to show the diff:\n"); - string munged_golden = golden_filename + ".munged"; - WriteToFile(golden, munged_golden); - string munged_captured = cap->filename() + ".munged"; - WriteToFile(captured, munged_captured); -#ifdef OS_WINDOWS - string diffcmd("fc " + munged_golden + " " + munged_captured); -#else - string diffcmd("diff -u " + munged_golden + " " + munged_captured); -#endif - if (system(diffcmd.c_str()) != 0) { - fprintf(stderr, "diff command was failed.\n"); - } - unlink(munged_golden.c_str()); - unlink(munged_captured.c_str()); - return false; - } - LOG(INFO) << "Diff was successful"; - return true; -} - -// Save flags used from logging_unittest.cc. -#ifndef HAVE_LIB_GFLAGS -struct FlagSaver { - FlagSaver() - : v_(FLAGS_v), - stderrthreshold_(FLAGS_stderrthreshold), - logtostderr_(FLAGS_logtostderr), - alsologtostderr_(FLAGS_alsologtostderr) {} - ~FlagSaver() { - FLAGS_v = v_; - FLAGS_stderrthreshold = stderrthreshold_; - FLAGS_logtostderr = logtostderr_; - FLAGS_alsologtostderr = alsologtostderr_; - } - int v_; - int stderrthreshold_; - bool logtostderr_; - bool alsologtostderr_; -}; -#endif - -class Thread { - public: - virtual ~Thread() {} - - void SetJoinable(bool) {} -#if defined(OS_WINDOWS) && !defined(OS_CYGWIN) - void Start() { - handle_ = CreateThread(NULL, - 0, - (LPTHREAD_START_ROUTINE)&Thread::InvokeThread, - (LPVOID)this, - 0, - &th_); - CHECK(handle_) << "CreateThread"; - } - void Join() { - WaitForSingleObject(handle_, INFINITE); - } -#elif defined(HAVE_PTHREAD) - void Start() { - pthread_create(&th_, NULL, &Thread::InvokeThread, this); - } - void Join() { - pthread_join(th_, NULL); - } -#else -# error No thread implementation. -#endif - - protected: - virtual void Run() = 0; - - private: - static void* InvokeThread(void* self) { - ((Thread*)self)->Run(); - return NULL; - } - -#if defined(OS_WINDOWS) && !defined(OS_CYGWIN) - HANDLE handle_; - DWORD th_; -#else - pthread_t th_; -#endif -}; - -static inline void SleepForMilliseconds(int t) { -#ifndef OS_WINDOWS -# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L - const struct timespec req = {0, t * 1000 * 1000}; - nanosleep(&req, NULL); -# else - usleep(t * 1000); -# endif -#else - Sleep(t); -#endif -} - -// Add hook for operator new to ensure there are no memory allocation. - -void (*g_new_hook)() = NULL; - -_END_GOOGLE_NAMESPACE_ - -void* operator new(size_t size) { - if (GOOGLE_NAMESPACE::g_new_hook) { - GOOGLE_NAMESPACE::g_new_hook(); - } - return malloc(size); -} - -void* operator new[](size_t size) { - return ::operator new(size); -} - -void operator delete(void* p) { - free(p); -} - -void operator delete[](void* p) { - ::operator delete(p); -} diff --git a/third_party/glog/src/logging.cc b/third_party/glog/src/logging.cc deleted file mode 100644 index ddcf91007358..000000000000 --- a/third_party/glog/src/logging.cc +++ /dev/null @@ -1,2344 +0,0 @@ -// Copyright (c) 1999, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite() - -#include "utilities.h" - -#include <algorithm> -#include <assert.h> -#include <iomanip> -#include <string> -#ifdef HAVE_UNISTD_H -# include <unistd.h> // For _exit. -#endif -#include <climits> -#include <sys/types.h> -#include <sys/stat.h> -#ifdef HAVE_SYS_UTSNAME_H -# include <sys/utsname.h> // For uname. -#endif -#include <time.h> -#include <fcntl.h> -#include <cstdio> -#include <iostream> -#include <stdarg.h> -#include <stdlib.h> -#ifdef HAVE_PWD_H -# include <pwd.h> -#endif -#ifdef HAVE_SYSLOG_H -# include <syslog.h> -#endif -#include <vector> -#include <errno.h> // for errno -#include <sstream> -#ifdef OS_WINDOWS -#include "windows/dirent.h" -#else -#include <dirent.h> // for automatic removal of old logs -#endif -#include "base/commandlineflags.h" // to get the program name -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "base/googleinit.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -using std::string; -using std::vector; -using std::setw; -using std::setfill; -using std::hex; -using std::dec; -using std::min; -using std::ostream; -using std::ostringstream; - -using std::FILE; -using std::fwrite; -using std::fclose; -using std::fflush; -using std::fprintf; -using std::perror; - -#ifdef __QNX__ -using std::fdopen; -#endif - -#ifdef _WIN32 -#define fdopen _fdopen -#endif - -// There is no thread annotation support. -#define EXCLUSIVE_LOCKS_REQUIRED(mu) - -static bool BoolFromEnv(const char *varname, bool defval) { - const char* const valstr = getenv(varname); - if (!valstr) { - return defval; - } - return memchr("tTyY1\0", valstr[0], 6) != NULL; -} - -GLOG_DEFINE_bool(timestamp_in_logfile_name, - BoolFromEnv("GOOGLE_TIMESTAMP_IN_LOGFILE_NAME", true), - "put a timestamp at the end of the log file name"); -GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), - "log messages go to stderr instead of logfiles"); -GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), - "log messages go to stderr in addition to logfiles"); -GLOG_DEFINE_bool(colorlogtostderr, false, - "color messages logged to stderr (if supported by terminal)"); -#ifdef OS_LINUX -GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " - "Logs can grow very quickly and they are rarely read before they " - "need to be evicted from memory. Instead, drop them from memory " - "as soon as they are flushed to disk."); -#endif - -// By default, errors (including fatal errors) get logged to stderr as -// well as the file. -// -// The default is ERROR instead of FATAL so that users can see problems -// when they run a program without having to look in another file. -DEFINE_int32(stderrthreshold, - GOOGLE_NAMESPACE::GLOG_ERROR, - "log messages at or above this level are copied to stderr in " - "addition to logfiles. This flag obsoletes --alsologtostderr."); - -GLOG_DEFINE_string(alsologtoemail, "", - "log messages go to these email addresses " - "in addition to logfiles"); -GLOG_DEFINE_bool(log_prefix, true, - "Prepend the log prefix to the start of each log line"); -GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " - "actually get logged anywhere"); -GLOG_DEFINE_int32(logbuflevel, 0, - "Buffer log messages logged at this level or lower" - " (-1 means don't buffer; 0 means buffer INFO only;" - " ...)"); -GLOG_DEFINE_int32(logbufsecs, 30, - "Buffer log messages for at most this many seconds"); -GLOG_DEFINE_int32(logemaillevel, 999, - "Email log messages logged at this level or higher" - " (0 means email all; 3 means email FATAL only;" - " ...)"); -GLOG_DEFINE_string(logmailer, "/bin/mail", - "Mailer used to send logging email"); - -// Compute the default value for --log_dir -static const char* DefaultLogDir() { - const char* env; - env = getenv("GOOGLE_LOG_DIR"); - if (env != NULL && env[0] != '\0') { - return env; - } - env = getenv("TEST_TMPDIR"); - if (env != NULL && env[0] != '\0') { - return env; - } - return ""; -} - -GLOG_DEFINE_int32(logfile_mode, 0664, "Log file mode/permissions."); - -GLOG_DEFINE_string(log_dir, DefaultLogDir(), - "If specified, logfiles are written into this directory instead " - "of the default logging directory."); -GLOG_DEFINE_string(log_link, "", "Put additional links to the log " - "files in this directory"); - -GLOG_DEFINE_int32(max_log_size, 1800, - "approx. maximum log file size (in MB). A value of 0 will " - "be silently overridden to 1."); - -GLOG_DEFINE_bool(stop_logging_if_full_disk, false, - "Stop attempting to log to disk if the disk is full."); - -GLOG_DEFINE_string(log_backtrace_at, "", - "Emit a backtrace when logging at file:linenum."); - -// TODO(hamaji): consider windows -#define PATH_SEPARATOR '/' - -#ifndef HAVE_PREAD -#if defined(OS_WINDOWS) -#include <basetsd.h> -#define ssize_t SSIZE_T -#endif -static ssize_t pread(int fd, void* buf, size_t count, off_t offset) { - off_t orig_offset = lseek(fd, 0, SEEK_CUR); - if (orig_offset == (off_t)-1) - return -1; - if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) - return -1; - ssize_t len = read(fd, buf, count); - if (len < 0) - return len; - if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) - return -1; - return len; -} -#endif // !HAVE_PREAD - -#ifndef HAVE_PWRITE -static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) { - off_t orig_offset = lseek(fd, 0, SEEK_CUR); - if (orig_offset == (off_t)-1) - return -1; - if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) - return -1; - ssize_t len = write(fd, buf, count); - if (len < 0) - return len; - if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) - return -1; - return len; -} -#endif // !HAVE_PWRITE - -static void GetHostName(string* hostname) { -#if defined(HAVE_SYS_UTSNAME_H) - struct utsname buf; - if (0 != uname(&buf)) { - // ensure null termination on failure - *buf.nodename = '\0'; - } - *hostname = buf.nodename; -#elif defined(OS_WINDOWS) - char buf[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD len = MAX_COMPUTERNAME_LENGTH + 1; - if (GetComputerNameA(buf, &len)) { - *hostname = buf; - } else { - hostname->clear(); - } -#else -# warning There is no way to retrieve the host name. - *hostname = "(unknown)"; -#endif -} - -// Returns true iff terminal supports using colors in output. -static bool TerminalSupportsColor() { - bool term_supports_color = false; -#ifdef OS_WINDOWS - // on Windows TERM variable is usually not set, but the console does - // support colors. - term_supports_color = true; -#else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = getenv("TERM"); - if (term != NULL && term[0] != '\0') { - term_supports_color = - !strcmp(term, "xterm") || - !strcmp(term, "xterm-color") || - !strcmp(term, "xterm-256color") || - !strcmp(term, "screen-256color") || - !strcmp(term, "konsole") || - !strcmp(term, "konsole-16color") || - !strcmp(term, "konsole-256color") || - !strcmp(term, "screen") || - !strcmp(term, "linux") || - !strcmp(term, "cygwin"); - } -#endif - return term_supports_color; -} - -_START_GOOGLE_NAMESPACE_ - -enum GLogColor { - COLOR_DEFAULT, - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW -}; - -static GLogColor SeverityToColor(LogSeverity severity) { - assert(severity >= 0 && severity < NUM_SEVERITIES); - GLogColor color = COLOR_DEFAULT; - switch (severity) { - case GLOG_INFO: - color = COLOR_DEFAULT; - break; - case GLOG_WARNING: - color = COLOR_YELLOW; - break; - case GLOG_ERROR: - case GLOG_FATAL: - color = COLOR_RED; - break; - default: - // should never get here. - assert(false); - } - return color; -} - -#ifdef OS_WINDOWS - -// Returns the character attribute for the given color. -static WORD GetColorAttribute(GLogColor color) { - switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; - default: return 0; - } -} - -#else - -// Returns the ANSI color code for the given color. -static const char* GetAnsiColorCode(GLogColor color) { - switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; - case COLOR_DEFAULT: return ""; - }; - return NULL; // stop warning about return type. -} - -#endif // OS_WINDOWS - -// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 -static int32 MaxLogSize() { - return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); -} - -// An arbitrary limit on the length of a single log message. This -// is so that streaming can be done more efficiently. -const size_t LogMessage::kMaxLogMessageLen = 30000; - -struct LogMessage::LogMessageData { - LogMessageData(); - - int preserved_errno_; // preserved errno - // Buffer space; contains complete message text. - char message_text_[LogMessage::kMaxLogMessageLen+1]; - LogStream stream_; - char severity_; // What level is this LogMessage logged at? - int line_; // line number where logging call is. - void (LogMessage::*send_method_)(); // Call this in destructor to send - union { // At most one of these is used: union to keep the size low. - LogSink* sink_; // NULL or sink to send message to - std::vector<std::string>* outvec_; // NULL or vector to push message onto - std::string* message_; // NULL or string to write message into - }; - time_t timestamp_; // Time of creation of LogMessage - struct ::tm tm_time_; // Time of creation of LogMessage - int32 usecs_; // Time of creation of LogMessage - microseconds part - size_t num_prefix_chars_; // # of chars of prefix in this message - size_t num_chars_to_log_; // # of chars of msg to send to log - size_t num_chars_to_syslog_; // # of chars of msg to send to syslog - const char* basename_; // basename of file that called LOG - const char* fullname_; // fullname of file that called LOG - bool has_been_flushed_; // false => data has not been flushed - bool first_fatal_; // true => this was first fatal msg - - private: - LogMessageData(const LogMessageData&); - void operator=(const LogMessageData&); -}; - -// A mutex that allows only one thread to log at a time, to keep things from -// getting jumbled. Some other very uncommon logging operations (like -// changing the destination file for log messages of a given severity) also -// lock this mutex. Please be sure that anybody who might possibly need to -// lock it does so. -static Mutex log_mutex; - -// Number of messages sent at each severity. Under log_mutex. -int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; - -// Globally disable log writing (if disk is full) -static bool stop_writing = false; - -const char*const LogSeverityNames[NUM_SEVERITIES] = { - "INFO", "WARNING", "ERROR", "FATAL" -}; - -// Has the user called SetExitOnDFatal(true)? -static bool exit_on_dfatal = true; - -const char* GetLogSeverityName(LogSeverity severity) { - return LogSeverityNames[severity]; -} - -static bool SendEmailInternal(const char*dest, const char *subject, - const char*body, bool use_logging); - -base::Logger::~Logger() { -} - -namespace { - -// Encapsulates all file-system related state -class LogFileObject : public base::Logger { - public: - LogFileObject(LogSeverity severity, const char* base_filename); - ~LogFileObject(); - - virtual void Write(bool force_flush, // Should we force a flush here? - time_t timestamp, // Timestamp for this entry - const char* message, - int message_len); - - // Configuration options - void SetBasename(const char* basename); - void SetExtension(const char* ext); - void SetSymlinkBasename(const char* symlink_basename); - - // Normal flushing routine - virtual void Flush(); - - // It is the actual file length for the system loggers, - // i.e., INFO, ERROR, etc. - virtual uint32 LogSize() { - MutexLock l(&lock_); - return file_length_; - } - - // Internal flush routine. Exposed so that FlushLogFilesUnsafe() - // can avoid grabbing a lock. Usually Flush() calls it after - // acquiring lock_. - void FlushUnlocked(); - - private: - static const uint32 kRolloverAttemptFrequency = 0x20; - - Mutex lock_; - bool base_filename_selected_; - string base_filename_; - string symlink_basename_; - string filename_extension_; // option users can specify (eg to add port#) - FILE* file_; - LogSeverity severity_; - uint32 bytes_since_flush_; - uint32 dropped_mem_length_; - uint32 file_length_; - unsigned int rollover_attempt_; - int64 next_flush_time_; // cycle count at which to flush log - - // Actually create a logfile using the value of base_filename_ and the - // optional argument time_pid_string - // REQUIRES: lock_ is held - bool CreateLogfile(const string& time_pid_string); -}; - -} // namespace - -class LogDestination { - public: - friend class LogMessage; - friend void ReprintFatalMessage(); - friend base::Logger* base::GetLogger(LogSeverity); - friend void base::SetLogger(LogSeverity, base::Logger*); - - // These methods are just forwarded to by their global versions. - static void SetLogDestination(LogSeverity severity, - const char* base_filename); - static void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - static void AddLogSink(LogSink *destination); - static void RemoveLogSink(LogSink *destination); - static void SetLogFilenameExtension(const char* filename_extension); - static void SetStderrLogging(LogSeverity min_severity); - static void SetEmailLogging(LogSeverity min_severity, const char* addresses); - static void LogToStderr(); - // Flush all log files that are at least at the given severity level - static void FlushLogFiles(int min_severity); - static void FlushLogFilesUnsafe(int min_severity); - - // we set the maximum size of our packet to be 1400, the logic being - // to prevent fragmentation. - // Really this number is arbitrary. - static const int kNetworkBytes = 1400; - - static const string& hostname(); - static const bool& terminal_supports_color() { - return terminal_supports_color_; - } - - static void DeleteLogDestinations(); - - private: - LogDestination(LogSeverity severity, const char* base_filename); - ~LogDestination(); - - // Take a log message of a particular severity and log it to stderr - // iff it's of a high enough severity to deserve it. - static void MaybeLogToStderr(LogSeverity severity, const char* message, - size_t len); - - // Take a log message of a particular severity and log it to email - // iff it's of a high enough severity to deserve it. - static void MaybeLogToEmail(LogSeverity severity, const char* message, - size_t len); - // Take a log message of a particular severity and log it to a file - // iff the base filename is not "" (which means "don't log to me") - static void MaybeLogToLogfile(LogSeverity severity, - time_t timestamp, - const char* message, size_t len); - // Take a log message of a particular severity and log it to the file - // for that severity and also for all files with severity less than - // this severity. - static void LogToAllLogfiles(LogSeverity severity, - time_t timestamp, - const char* message, size_t len); - - // Send logging info to all registered sinks. - static void LogToSinks(LogSeverity severity, - const char *full_filename, - const char *base_filename, - int line, - const struct ::tm* tm_time, - const char* message, - size_t message_len, - int32 usecs); - - // Wait for all registered sinks via WaitTillSent - // including the optional one in "data". - static void WaitForSinks(LogMessage::LogMessageData* data); - - static LogDestination* log_destination(LogSeverity severity); - - LogFileObject fileobject_; - base::Logger* logger_; // Either &fileobject_, or wrapper around it - - static LogDestination* log_destinations_[NUM_SEVERITIES]; - static LogSeverity email_logging_severity_; - static string addresses_; - static string hostname_; - static bool terminal_supports_color_; - - // arbitrary global logging destinations. - static vector<LogSink*>* sinks_; - - // Protects the vector sinks_, - // but not the LogSink objects its elements reference. - static Mutex sink_mutex_; - - // Disallow - LogDestination(const LogDestination&); - LogDestination& operator=(const LogDestination&); -}; - -// Errors do not get logged to email by default. -LogSeverity LogDestination::email_logging_severity_ = 99999; - -string LogDestination::addresses_; -string LogDestination::hostname_; - -vector<LogSink*>* LogDestination::sinks_ = NULL; -Mutex LogDestination::sink_mutex_; -bool LogDestination::terminal_supports_color_ = TerminalSupportsColor(); - -/* static */ -const string& LogDestination::hostname() { - if (hostname_.empty()) { - GetHostName(&hostname_); - if (hostname_.empty()) { - hostname_ = "(unknown)"; - } - } - return hostname_; -} - -LogDestination::LogDestination(LogSeverity severity, - const char* base_filename) - : fileobject_(severity, base_filename), - logger_(&fileobject_) { -} - -LogDestination::~LogDestination() { - if (logger_ && logger_ != &fileobject_) { - // Delete user-specified logger set via SetLogger(). - delete logger_; - } -} - -inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { - // assume we have the log_mutex or we simply don't care - // about it - for (int i = min_severity; i < NUM_SEVERITIES; i++) { - LogDestination* log = log_destinations_[i]; - if (log != NULL) { - // Flush the base fileobject_ logger directly instead of going - // through any wrappers to reduce chance of deadlock. - log->fileobject_.FlushUnlocked(); - } - } -} - -inline void LogDestination::FlushLogFiles(int min_severity) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - for (int i = min_severity; i < NUM_SEVERITIES; i++) { - LogDestination* log = log_destination(i); - if (log != NULL) { - log->logger_->Flush(); - } - } -} - -inline void LogDestination::SetLogDestination(LogSeverity severity, - const char* base_filename) { - assert(severity >= 0 && severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - log_destination(severity)->fileobject_.SetBasename(base_filename); -} - -inline void LogDestination::SetLogSymlink(LogSeverity severity, - const char* symlink_basename) { - CHECK_GE(severity, 0); - CHECK_LT(severity, NUM_SEVERITIES); - MutexLock l(&log_mutex); - log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename); -} - -inline void LogDestination::AddLogSink(LogSink *destination) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&sink_mutex_); - if (!sinks_) sinks_ = new vector<LogSink*>; - sinks_->push_back(destination); -} - -inline void LogDestination::RemoveLogSink(LogSink *destination) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&sink_mutex_); - // This doesn't keep the sinks in order, but who cares? - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - if ((*sinks_)[i] == destination) { - (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; - sinks_->pop_back(); - break; - } - } - } -} - -inline void LogDestination::SetLogFilenameExtension(const char* ext) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) { - log_destination(severity)->fileobject_.SetExtension(ext); - } -} - -inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { - assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - FLAGS_stderrthreshold = min_severity; -} - -inline void LogDestination::LogToStderr() { - // *Don't* put this stuff in a mutex lock, since SetStderrLogging & - // SetLogDestination already do the locking! - SetStderrLogging(0); // thus everything is "also" logged to stderr - for ( int i = 0; i < NUM_SEVERITIES; ++i ) { - SetLogDestination(i, ""); // "" turns off logging to a logfile - } -} - -inline void LogDestination::SetEmailLogging(LogSeverity min_severity, - const char* addresses) { - assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - LogDestination::email_logging_severity_ = min_severity; - LogDestination::addresses_ = addresses; -} - -static void ColoredWriteToStderr(LogSeverity severity, - const char* message, size_t len) { - const GLogColor color = - (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ? - SeverityToColor(severity) : COLOR_DEFAULT; - - // Avoid using cerr from this module since we may get called during - // exit code, and cerr may be partially or fully destroyed by then. - if (COLOR_DEFAULT == color) { - fwrite(message, len, 1, stderr); - return; - } -#ifdef OS_WINDOWS - const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stderr_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; - - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - fflush(stderr); - SetConsoleTextAttribute(stderr_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - fwrite(message, len, 1, stderr); - fflush(stderr); - // Restores the text color. - SetConsoleTextAttribute(stderr_handle, old_color_attrs); -#else - fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color)); - fwrite(message, len, 1, stderr); - fprintf(stderr, "\033[m"); // Resets the terminal to default. -#endif // OS_WINDOWS -} - -static void WriteToStderr(const char* message, size_t len) { - // Avoid using cerr from this module since we may get called during - // exit code, and cerr may be partially or fully destroyed by then. - fwrite(message, len, 1, stderr); -} - -inline void LogDestination::MaybeLogToStderr(LogSeverity severity, - const char* message, size_t len) { - if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { - ColoredWriteToStderr(severity, message, len); -#ifdef OS_WINDOWS - // On Windows, also output to the debugger - ::OutputDebugStringA(string(message,len).c_str()); -#endif - } -} - - -inline void LogDestination::MaybeLogToEmail(LogSeverity severity, - const char* message, size_t len) { - if (severity >= email_logging_severity_ || - severity >= FLAGS_logemaillevel) { - string to(FLAGS_alsologtoemail); - if (!addresses_.empty()) { - if (!to.empty()) { - to += ","; - } - to += addresses_; - } - const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " + - glog_internal_namespace_::ProgramInvocationShortName()); - string body(hostname()); - body += "\n\n"; - body.append(message, len); - - // should NOT use SendEmail(). The caller of this function holds the - // log_mutex and SendEmail() calls LOG/VLOG which will block trying to - // acquire the log_mutex object. Use SendEmailInternal() and set - // use_logging to false. - SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false); - } -} - - -inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, - time_t timestamp, - const char* message, - size_t len) { - const bool should_flush = severity > FLAGS_logbuflevel; - LogDestination* destination = log_destination(severity); - destination->logger_->Write(should_flush, timestamp, message, len); -} - -inline void LogDestination::LogToAllLogfiles(LogSeverity severity, - time_t timestamp, - const char* message, - size_t len) { - - if ( FLAGS_logtostderr ) { // global flag: never log to file - ColoredWriteToStderr(severity, message, len); - } else { - for (int i = severity; i >= 0; --i) - LogDestination::MaybeLogToLogfile(i, timestamp, message, len); - } -} - -inline void LogDestination::LogToSinks(LogSeverity severity, - const char *full_filename, - const char *base_filename, - int line, - const struct ::tm* tm_time, - const char* message, - size_t message_len, - int32 usecs) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - (*sinks_)[i]->send(severity, full_filename, base_filename, - line, tm_time, message, message_len, usecs); - } - } -} - -inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - (*sinks_)[i]->WaitTillSent(); - } - } - const bool send_to_sink = - (data->send_method_ == &LogMessage::SendToSink) || - (data->send_method_ == &LogMessage::SendToSinkAndLog); - if (send_to_sink && data->sink_ != NULL) { - data->sink_->WaitTillSent(); - } -} - -LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; - -inline LogDestination* LogDestination::log_destination(LogSeverity severity) { - assert(severity >=0 && severity < NUM_SEVERITIES); - if (!log_destinations_[severity]) { - log_destinations_[severity] = new LogDestination(severity, NULL); - } - return log_destinations_[severity]; -} - -void LogDestination::DeleteLogDestinations() { - for (int severity = 0; severity < NUM_SEVERITIES; ++severity) { - delete log_destinations_[severity]; - log_destinations_[severity] = NULL; - } - MutexLock l(&sink_mutex_); - delete sinks_; - sinks_ = NULL; -} - -namespace { - -bool IsGlogLog(const string& filename) { - // Check if filename matches the pattern of a glog file: - // "<program name>.<hostname>.<user name>.log...". - const int kKeywordCount = 4; - std::string keywords[kKeywordCount] = { - glog_internal_namespace_::ProgramInvocationShortName(), - LogDestination::hostname(), - MyUserName(), - "log" - }; - - int start_pos = 0; - for (int i = 0; i < kKeywordCount; i++) { - if (filename.find(keywords[i], start_pos) == filename.npos) { - return false; - } - start_pos += keywords[i].size() + 1; - } - return true; -} - -bool LastModifiedOver(const string& filepath, int days) { - // Try to get the last modified time of this file. - struct stat file_stat; - - if (stat(filepath.c_str(), &file_stat) == 0) { - // A day is 86400 seconds, so 7 days is 86400 * 7 = 604800 seconds. - time_t last_modified_time = file_stat.st_mtime; - time_t current_time = time(NULL); - return difftime(current_time, last_modified_time) > days * 86400; - } - - // If failed to get file stat, don't return true! - return false; -} - -vector<string> GetOverdueLogNames(string log_directory, int days) { - // The names of overdue logs. - vector<string> overdue_log_names; - - // Try to get all files within log_directory. - DIR *dir; - struct dirent *ent; - - char dir_delim = '/'; -#ifdef OS_WINDOWS - dir_delim = '\\'; -#endif - - // If log_directory doesn't end with a slash, append a slash to it. - if (log_directory.at(log_directory.size() - 1) != dir_delim) { - log_directory += dir_delim; - } - - if ((dir=opendir(log_directory.c_str()))) { - while ((ent=readdir(dir))) { - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { - continue; - } - string filepath = log_directory + ent->d_name; - if (IsGlogLog(ent->d_name) && LastModifiedOver(filepath, days)) { - overdue_log_names.push_back(filepath); - } - } - closedir(dir); - } - - return overdue_log_names; -} - -// Is log_cleaner enabled? -// This option can be enabled by calling google::EnableLogCleaner(days) -bool log_cleaner_enabled_; -int log_cleaner_overdue_days_ = 7; - -} // namespace - - -namespace { - -LogFileObject::LogFileObject(LogSeverity severity, - const char* base_filename) - : base_filename_selected_(base_filename != NULL), - base_filename_((base_filename != NULL) ? base_filename : ""), - symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), - filename_extension_(), - file_(NULL), - severity_(severity), - bytes_since_flush_(0), - dropped_mem_length_(0), - file_length_(0), - rollover_attempt_(kRolloverAttemptFrequency-1), - next_flush_time_(0) { - assert(severity >= 0); - assert(severity < NUM_SEVERITIES); -} - -LogFileObject::~LogFileObject() { - MutexLock l(&lock_); - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - } -} - -void LogFileObject::SetBasename(const char* basename) { - MutexLock l(&lock_); - base_filename_selected_ = true; - if (base_filename_ != basename) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - base_filename_ = basename; - } -} - -void LogFileObject::SetExtension(const char* ext) { - MutexLock l(&lock_); - if (filename_extension_ != ext) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - filename_extension_ = ext; - } -} - -void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { - MutexLock l(&lock_); - symlink_basename_ = symlink_basename; -} - -void LogFileObject::Flush() { - MutexLock l(&lock_); - FlushUnlocked(); -} - -void LogFileObject::FlushUnlocked(){ - if (file_ != NULL) { - fflush(file_); - bytes_since_flush_ = 0; - } - // Figure out when we are due for another flush. - const int64 next = (FLAGS_logbufsecs - * static_cast<int64>(1000000)); // in usec - next_flush_time_ = CycleClock_Now() + UsecToCycles(next); -} - -bool LogFileObject::CreateLogfile(const string& time_pid_string) { - string string_filename = base_filename_+filename_extension_; - if (FLAGS_timestamp_in_logfile_name) { - string_filename += time_pid_string; - } - const char* filename = string_filename.c_str(); - //only write to files, create if non-existant. - int flags = O_WRONLY | O_CREAT; - if (FLAGS_timestamp_in_logfile_name) { - //demand that the file is unique for our timestamp (fail if it exists). - flags = flags | O_EXCL; - } - int fd = open(filename, flags, FLAGS_logfile_mode); - if (fd == -1) return false; -#ifdef HAVE_FCNTL - // Mark the file close-on-exec. We don't really care if this fails - fcntl(fd, F_SETFD, FD_CLOEXEC); - - // Mark the file as exclusive write access to avoid two clients logging to the - // same file. This applies particularly when !FLAGS_timestamp_in_logfile_name - // (otherwise open would fail because the O_EXCL flag on similar filename). - // locks are released on unlock or close() automatically, only after log is - // released. - // This will work after a fork as it is not inherited (not stored in the fd). - // Lock will not be lost because the file is opened with exclusive lock (write) - // and we will never read from it inside the process. - // TODO windows implementation of this (as flock is not available on mingw). - static struct flock w_lock; - - w_lock.l_type = F_WRLCK; - w_lock.l_start = 0; - w_lock.l_whence = SEEK_SET; - w_lock.l_len = 0; - - int wlock_ret = fcntl(fd, F_SETLK, &w_lock); - if (wlock_ret == -1) { - close(fd); //as we are failing already, do not check errors here - return false; - } -#endif - - //fdopen in append mode so if the file exists it will fseek to the end - file_ = fdopen(fd, "a"); // Make a FILE*. - if (file_ == NULL) { // Man, we're screwed! - close(fd); - if (FLAGS_timestamp_in_logfile_name) { - unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it. - } - return false; - } -#ifdef OS_WINDOWS - // https://github.com/golang/go/issues/27638 - make sure we seek to the end to append - // empirically replicated with wine over mingw build - if (!FLAGS_timestamp_in_logfile_name) { - if (fseek(file_, 0, SEEK_END) != 0) { - return false; - } - } -#endif - // We try to create a symlink called <program_name>.<severity>, - // which is easier to use. (Every time we create a new logfile, - // we destroy the old symlink and create a new one, so it always - // points to the latest logfile.) If it fails, we're sad but it's - // no error. - if (!symlink_basename_.empty()) { - // take directory from filename - const char* slash = strrchr(filename, PATH_SEPARATOR); - const string linkname = - symlink_basename_ + '.' + LogSeverityNames[severity_]; - string linkpath; - if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname - linkpath += linkname; - unlink(linkpath.c_str()); // delete old one if it exists - -#if defined(OS_WINDOWS) - // TODO(hamaji): Create lnk file on Windows? -#elif defined(HAVE_UNISTD_H) - // We must have unistd.h. - // Make the symlink be relative (in the same dir) so that if the - // entire log directory gets relocated the link is still valid. - const char *linkdest = slash ? (slash + 1) : filename; - if (symlink(linkdest, linkpath.c_str()) != 0) { - // silently ignore failures - } - - // Make an additional link to the log file in a place specified by - // FLAGS_log_link, if indicated - if (!FLAGS_log_link.empty()) { - linkpath = FLAGS_log_link + "/" + linkname; - unlink(linkpath.c_str()); // delete old one if it exists - if (symlink(filename, linkpath.c_str()) != 0) { - // silently ignore failures - } - } -#endif - } - - return true; // Everything worked -} - -void LogFileObject::Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) { - MutexLock l(&lock_); - - // We don't log if the base_name_ is "" (which means "don't write") - if (base_filename_selected_ && base_filename_.empty()) { - return; - } - - if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() || - PidHasChanged()) { - if (file_ != NULL) fclose(file_); - file_ = NULL; - file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - - // If there's no destination file, make one before outputting - if (file_ == NULL) { - // Try to rollover the log file every 32 log messages. The only time - // this could matter would be when we have trouble creating the log - // file. If that happens, we'll lose lots of log messages, of course! - if (++rollover_attempt_ != kRolloverAttemptFrequency) return; - rollover_attempt_ = 0; - - struct ::tm tm_time; - localtime_r(×tamp, &tm_time); - - // The logfile's filename will have the date/time & pid in it - ostringstream time_pid_stream; - time_pid_stream.fill('0'); - time_pid_stream << 1900+tm_time.tm_year - << setw(2) << 1+tm_time.tm_mon - << setw(2) << tm_time.tm_mday - << '-' - << setw(2) << tm_time.tm_hour - << setw(2) << tm_time.tm_min - << setw(2) << tm_time.tm_sec - << '.' - << GetMainThreadPid(); - const string& time_pid_string = time_pid_stream.str(); - - if (base_filename_selected_) { - if (!CreateLogfile(time_pid_string)) { - perror("Could not create log file"); - fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", - time_pid_string.c_str()); - return; - } - } else { - // If no base filename for logs of this severity has been set, use a - // default base filename of - // "<program name>.<hostname>.<user name>.log.<severity level>.". So - // logfiles will have names like - // webserver.examplehost.root.log.INFO.19990817-150000.4354, where - // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00), - // and 4354 is the pid of the logging process. The date & time reflect - // when the file was created for output. - // - // Where does the file get put? Successively try the directories - // "/tmp", and "." - string stripped_filename( - glog_internal_namespace_::ProgramInvocationShortName()); - string hostname; - GetHostName(&hostname); - - string uidname = MyUserName(); - // We should not call CHECK() here because this function can be - // called after holding on to log_mutex. We don't want to - // attempt to hold on to the same mutex, and get into a - // deadlock. Simply use a name like invalid-user. - if (uidname.empty()) uidname = "invalid-user"; - - stripped_filename = stripped_filename+'.'+hostname+'.' - +uidname+".log." - +LogSeverityNames[severity_]+'.'; - // We're going to (potentially) try to put logs in several different dirs - const vector<string> & log_dirs = GetLoggingDirectories(); - - // Go through the list of dirs, and try to create the log file in each - // until we succeed or run out of options - bool success = false; - for (vector<string>::const_iterator dir = log_dirs.begin(); - dir != log_dirs.end(); - ++dir) { - base_filename_ = *dir + "/" + stripped_filename; - if ( CreateLogfile(time_pid_string) ) { - success = true; - break; - } - } - // If we never succeeded, we have to give up - if ( success == false ) { - perror("Could not create logging file"); - fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", - time_pid_string.c_str()); - return; - } - } - - // Write a header message into the log file - ostringstream file_header_stream; - file_header_stream.fill('0'); - file_header_stream << "Log file created at: " - << 1900+tm_time.tm_year << '/' - << setw(2) << 1+tm_time.tm_mon << '/' - << setw(2) << tm_time.tm_mday - << ' ' - << setw(2) << tm_time.tm_hour << ':' - << setw(2) << tm_time.tm_min << ':' - << setw(2) << tm_time.tm_sec << '\n' - << "Running on machine: " - << LogDestination::hostname() << '\n' - << "Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu " - << "threadid file:line] msg" << '\n'; - const string& file_header_string = file_header_stream.str(); - - const int header_len = file_header_string.size(); - fwrite(file_header_string.data(), 1, header_len, file_); - file_length_ += header_len; - bytes_since_flush_ += header_len; - } - - // Write to LOG file - if ( !stop_writing ) { - // fwrite() doesn't return an error when the disk is full, for - // messages that are less than 4096 bytes. When the disk is full, - // it returns the message length for messages that are less than - // 4096 bytes. fwrite() returns 4096 for message lengths that are - // greater than 4096, thereby indicating an error. - errno = 0; - fwrite(message, 1, message_len, file_); - if ( FLAGS_stop_logging_if_full_disk && - errno == ENOSPC ) { // disk full, stop writing to disk - stop_writing = true; // until the disk is - return; - } else { - file_length_ += message_len; - bytes_since_flush_ += message_len; - } - } else { - if ( CycleClock_Now() >= next_flush_time_ ) - stop_writing = false; // check to see if disk has free space. - return; // no need to flush - } - - // See important msgs *now*. Also, flush logs at least every 10^6 chars, - // or every "FLAGS_logbufsecs" seconds. - if ( force_flush || - (bytes_since_flush_ >= 1000000) || - (CycleClock_Now() >= next_flush_time_) ) { - FlushUnlocked(); -#ifdef OS_LINUX - // Only consider files >= 3MiB - if (FLAGS_drop_log_memory && file_length_ >= (3 << 20)) { - // Don't evict the most recent 1-2MiB so as not to impact a tailer - // of the log file and to avoid page rounding issue on linux < 4.7 - uint32 total_drop_length = (file_length_ & ~((1 << 20) - 1)) - (1 << 20); - uint32 this_drop_length = total_drop_length - dropped_mem_length_; - if (this_drop_length >= (2 << 20)) { - // Only advise when >= 2MiB to drop -# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21) - // 'posix_fadvise' introduced in API 21: - // * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732 -# else - posix_fadvise(fileno(file_), dropped_mem_length_, this_drop_length, - POSIX_FADV_DONTNEED); -# endif - dropped_mem_length_ = total_drop_length; - } - } -#endif - // Perform clean up for old logs - if (log_cleaner_enabled_) { - const vector<string>& dirs = GetLoggingDirectories(); - for (size_t i = 0; i < dirs.size(); i++) { - vector<string> logs = GetOverdueLogNames(dirs[i], log_cleaner_overdue_days_); - for (size_t j = 0; j < logs.size(); j++) { - static_cast<void>(unlink(logs[j].c_str())); - } - } - } - } -} - -} // namespace - -// Static log data space to avoid alloc failures in a LOG(FATAL) -// -// Since multiple threads may call LOG(FATAL), and we want to preserve -// the data from the first call, we allocate two sets of space. One -// for exclusive use by the first thread, and one for shared use by -// all other threads. -static Mutex fatal_msg_lock; -static CrashReason crash_reason; -static bool fatal_msg_exclusive = true; -static LogMessage::LogMessageData fatal_msg_data_exclusive; -static LogMessage::LogMessageData fatal_msg_data_shared; - -#ifdef GLOG_THREAD_LOCAL_STORAGE -// Static thread-local log data space to use, because typically at most one -// LogMessageData object exists (in this case glog makes zero heap memory -// allocations). -static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true; - -#ifdef HAVE_ALIGNED_STORAGE -static GLOG_THREAD_LOCAL_STORAGE - std::aligned_storage<sizeof(LogMessage::LogMessageData), - alignof(LogMessage::LogMessageData)>::type thread_msg_data; -#else -static GLOG_THREAD_LOCAL_STORAGE - char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)]; -#endif // HAVE_ALIGNED_STORAGE -#endif // defined(GLOG_THREAD_LOCAL_STORAGE) - -LogMessage::LogMessageData::LogMessageData() - : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - int ctr, void (LogMessage::*send_method)()) - : allocated_(NULL) { - Init(file, line, severity, send_method); - data_->stream_.set_ctr(ctr); -} - -LogMessage::LogMessage(const char* file, int line, - const CheckOpString& result) - : allocated_(NULL) { - Init(file, line, GLOG_FATAL, &LogMessage::SendToLog); - stream() << "Check failed: " << (*result.str_) << " "; -} - -LogMessage::LogMessage(const char* file, int line) - : allocated_(NULL) { - Init(file, line, GLOG_INFO, &LogMessage::SendToLog); -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::SendToLog); -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - LogSink* sink, bool also_send_to_log) - : allocated_(NULL) { - Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : - &LogMessage::SendToSink); - data_->sink_ = sink; // override Init()'s setting to NULL -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - vector<string> *outvec) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::SaveOrSendToLog); - data_->outvec_ = outvec; // override Init()'s setting to NULL -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - string *message) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::WriteToStringAndLog); - data_->message_ = message; // override Init()'s setting to NULL -} - -void LogMessage::Init(const char* file, - int line, - LogSeverity severity, - void (LogMessage::*send_method)()) { - allocated_ = NULL; - if (severity != GLOG_FATAL || !exit_on_dfatal) { -#ifdef GLOG_THREAD_LOCAL_STORAGE - // No need for locking, because this is thread local. - if (thread_data_available) { - thread_data_available = false; -#ifdef HAVE_ALIGNED_STORAGE - data_ = new (&thread_msg_data) LogMessageData; -#else - const uintptr_t kAlign = sizeof(void*) - 1; - - char* align_ptr = - reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign); - data_ = new (align_ptr) LogMessageData; - assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0); -#endif - } else { - allocated_ = new LogMessageData(); - data_ = allocated_; - } -#else // !defined(GLOG_THREAD_LOCAL_STORAGE) - allocated_ = new LogMessageData(); - data_ = allocated_; -#endif // defined(GLOG_THREAD_LOCAL_STORAGE) - data_->first_fatal_ = false; - } else { - MutexLock l(&fatal_msg_lock); - if (fatal_msg_exclusive) { - fatal_msg_exclusive = false; - data_ = &fatal_msg_data_exclusive; - data_->first_fatal_ = true; - } else { - data_ = &fatal_msg_data_shared; - data_->first_fatal_ = false; - } - } - - stream().fill('0'); - data_->preserved_errno_ = errno; - data_->severity_ = severity; - data_->line_ = line; - data_->send_method_ = send_method; - data_->sink_ = NULL; - data_->outvec_ = NULL; - WallTime now = WallTime_Now(); - data_->timestamp_ = static_cast<time_t>(now); - localtime_r(&data_->timestamp_, &data_->tm_time_); - data_->usecs_ = static_cast<int32>((now - data_->timestamp_) * 1000000); - - data_->num_chars_to_log_ = 0; - data_->num_chars_to_syslog_ = 0; - data_->basename_ = const_basename(file); - data_->fullname_ = file; - data_->has_been_flushed_ = false; - - // If specified, prepend a prefix to each line. For example: - // I20201018 160715 f5d4fbb0 logging.cc:1153] - // (log level, GMT year, month, date, time, thread_id, file basename, line) - // We exclude the thread_id for the default thread. - if (FLAGS_log_prefix && (line != kNoLogPrefix)) { - stream() << LogSeverityNames[severity][0] - << setw(4) << 1900+data_->tm_time_.tm_year - << setw(2) << 1+data_->tm_time_.tm_mon - << setw(2) << data_->tm_time_.tm_mday - << ' ' - << setw(2) << data_->tm_time_.tm_hour << ':' - << setw(2) << data_->tm_time_.tm_min << ':' - << setw(2) << data_->tm_time_.tm_sec << "." - << setw(6) << data_->usecs_ - << ' ' - << setfill(' ') << setw(5) - << static_cast<unsigned int>(GetTID()) << setfill('0') - << ' ' - << data_->basename_ << ':' << data_->line_ << "] "; - } - data_->num_prefix_chars_ = data_->stream_.pcount(); - - if (!FLAGS_log_backtrace_at.empty()) { - char fileline[128]; - snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); -#ifdef HAVE_STACKTRACE - if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) { - string stacktrace; - DumpStackTraceToString(&stacktrace); - stream() << " (stacktrace:\n" << stacktrace << ") "; - } -#endif - } -} - -LogMessage::~LogMessage() { - Flush(); -#ifdef GLOG_THREAD_LOCAL_STORAGE - if (data_ == static_cast<void*>(&thread_msg_data)) { - data_->~LogMessageData(); - thread_data_available = true; - } - else { - delete allocated_; - } -#else // !defined(GLOG_THREAD_LOCAL_STORAGE) - delete allocated_; -#endif // defined(GLOG_THREAD_LOCAL_STORAGE) -} - -int LogMessage::preserved_errno() const { - return data_->preserved_errno_; -} - -ostream& LogMessage::stream() { - return data_->stream_; -} - -// Flush buffered message, called by the destructor, or any other function -// that needs to synchronize the log. -void LogMessage::Flush() { - if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) - return; - - data_->num_chars_to_log_ = data_->stream_.pcount(); - data_->num_chars_to_syslog_ = - data_->num_chars_to_log_ - data_->num_prefix_chars_; - - // Do we need to add a \n to the end of this message? - bool append_newline = - (data_->message_text_[data_->num_chars_to_log_-1] != '\n'); - char original_final_char = '\0'; - - // If we do need to add a \n, we'll do it by violating the memory of the - // ostrstream buffer. This is quick, and we'll make sure to undo our - // modification before anything else is done with the ostrstream. It - // would be preferable not to do things this way, but it seems to be - // the best way to deal with this. - if (append_newline) { - original_final_char = data_->message_text_[data_->num_chars_to_log_]; - data_->message_text_[data_->num_chars_to_log_++] = '\n'; - } - - // Prevent any subtle race conditions by wrapping a mutex lock around - // the actual logging action per se. - { - MutexLock l(&log_mutex); - (this->*(data_->send_method_))(); - ++num_messages_[static_cast<int>(data_->severity_)]; - } - LogDestination::WaitForSinks(data_); - - if (append_newline) { - // Fix the ostrstream back how it was before we screwed with it. - // It's 99.44% certain that we don't need to worry about doing this. - data_->message_text_[data_->num_chars_to_log_-1] = original_final_char; - } - - // If errno was already set before we enter the logging call, we'll - // set it back to that value when we return from the logging call. - // It happens often that we log an error message after a syscall - // failure, which can potentially set the errno to some other - // values. We would like to preserve the original errno. - if (data_->preserved_errno_ != 0) { - errno = data_->preserved_errno_; - } - - // Note that this message is now safely logged. If we're asked to flush - // again, as a result of destruction, say, we'll do nothing on future calls. - data_->has_been_flushed_ = true; -} - -// Copy of first FATAL log message so that we can print it out again -// after all the stack traces. To preserve legacy behavior, we don't -// use fatal_msg_data_exclusive. -static time_t fatal_time; -static char fatal_message[256]; - -void ReprintFatalMessage() { - if (fatal_message[0]) { - const int n = strlen(fatal_message); - if (!FLAGS_logtostderr) { - // Also write to stderr (don't color to avoid terminal checks) - WriteToStderr(fatal_message, n); - } - LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n); - } -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - static bool already_warned_before_initgoogle = false; - - log_mutex.AssertHeld(); - - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - - // Messages of a given severity get logged to lower severity logs, too - - if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) { - const char w[] = "WARNING: Logging before InitGoogleLogging() is " - "written to STDERR\n"; - WriteToStderr(w, strlen(w)); - already_warned_before_initgoogle = true; - } - - // global flag: never log to file if set. Also -- don't log to a - // file if we haven't parsed the command line flags to get the - // program name. - if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { - ColoredWriteToStderr(data_->severity_, - data_->message_text_, data_->num_chars_to_log_); - - // this could be protected by a flag if necessary. - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1), - data_->usecs_); - } else { - - // log this message to all log files of severity <= severity_ - LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_, - data_->message_text_, - data_->num_chars_to_log_); - - LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1), - data_->usecs_); - // NOTE: -1 removes trailing \n - } - - // If we log a FATAL message, flush all the log destinations, then toss - // a signal for others to catch. We leave the logs in a state that - // someone else can use them (as long as they flush afterwards) - if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) { - if (data_->first_fatal_) { - // Store crash information so that it is accessible from within signal - // handlers that may be invoked later. - RecordCrashReason(&crash_reason); - SetCrashReason(&crash_reason); - - // Store shortened fatal message for other logs and GWQ status - const int copy = min<int>(data_->num_chars_to_log_, - sizeof(fatal_message)-1); - memcpy(fatal_message, data_->message_text_, copy); - fatal_message[copy] = '\0'; - fatal_time = data_->timestamp_; - } - - if (!FLAGS_logtostderr) { - for (int i = 0; i < NUM_SEVERITIES; ++i) { - if ( LogDestination::log_destinations_[i] ) - LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); - } - } - - // release the lock that our caller (directly or indirectly) - // LogMessage::~LogMessage() grabbed so that signal handlers - // can use the logging facility. Alternately, we could add - // an entire unsafe logging interface to bypass locking - // for signal handlers but this seems simpler. - log_mutex.Unlock(); - LogDestination::WaitForSinks(data_); - - const char* message = "*** Check failure stack trace: ***\n"; - if (write(STDERR_FILENO, message, strlen(message)) < 0) { - // Ignore errors. - } - Fail(); - } -} - -void LogMessage::RecordCrashReason( - glog_internal_namespace_::CrashReason* reason) { - reason->filename = fatal_msg_data_exclusive.fullname_; - reason->line_number = fatal_msg_data_exclusive.line_; - reason->message = fatal_msg_data_exclusive.message_text_ + - fatal_msg_data_exclusive.num_prefix_chars_; -#ifdef HAVE_STACKTRACE - // Retrieve the stack trace, omitting the logging frames that got us here. - reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); -#else - reason->depth = 0; -#endif -} - -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NORETURN __attribute__((noreturn)) -#else -# define ATTRIBUTE_NORETURN -#endif - -#if defined(OS_WINDOWS) -__declspec(noreturn) -#endif -static void logging_fail() ATTRIBUTE_NORETURN; - -static void logging_fail() { - abort(); -} - -typedef void (*logging_fail_func_t)() ATTRIBUTE_NORETURN; - -GOOGLE_GLOG_DLL_DECL -logging_fail_func_t g_logging_fail_func = &logging_fail; - -void InstallFailureFunction(void (*fail_func)()) { - g_logging_fail_func = (logging_fail_func_t)fail_func; -} - -void LogMessage::Fail() { - g_logging_fail_func(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->sink_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1), - data_->usecs_); - } -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - SendToSink(); - SendToLog(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->outvec_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - // Omit prefix of message and trailing newline when recording in outvec_. - const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; - data_->outvec_->push_back(string(start, len)); - } else { - SendToLog(); - } -} - -void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->message_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - // Omit prefix of message and trailing newline when writing to message_. - const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; - data_->message_->assign(start, len); - } - SendToLog(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSyslogAndLog() { -#ifdef HAVE_SYSLOG_H - // Before any calls to syslog(), make a single call to openlog() - static bool openlog_already_called = false; - if (!openlog_already_called) { - openlog(glog_internal_namespace_::ProgramInvocationShortName(), - LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_USER); - openlog_already_called = true; - } - - // This array maps Google severity levels to syslog levels - const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; - syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s", - int(data_->num_chars_to_syslog_), - data_->message_text_ + data_->num_prefix_chars_); - SendToLog(); -#else - LOG(ERROR) << "No syslog support: message=" << data_->message_text_; -#endif -} - -base::Logger* base::GetLogger(LogSeverity severity) { - MutexLock l(&log_mutex); - return LogDestination::log_destination(severity)->logger_; -} - -void base::SetLogger(LogSeverity severity, base::Logger* logger) { - MutexLock l(&log_mutex); - LogDestination::log_destination(severity)->logger_ = logger; -} - -// L < log_mutex. Acquires and releases mutex_. -int64 LogMessage::num_messages(int severity) { - MutexLock l(&log_mutex); - return num_messages_[severity]; -} - -// Output the COUNTER value. This is only valid if ostream is a -// LogStream. -ostream& operator<<(ostream &os, const PRIVATE_Counter&) { -#ifdef DISABLE_RTTI - LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os); -#else - LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os); -#endif - CHECK(log && log == log->self()) - << "You must not use COUNTER with non-glog ostream"; - os << log->ctr(); - return os; -} - -ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, - LogSeverity severity, int ctr, - void (LogMessage::*send_method)()) - : LogMessage(file, line, severity, ctr, send_method) { -} - -ErrnoLogMessage::~ErrnoLogMessage() { - // Don't access errno directly because it may have been altered - // while streaming the message. - stream() << ": " << StrError(preserved_errno()) << " [" - << preserved_errno() << "]"; -} - -void FlushLogFiles(LogSeverity min_severity) { - LogDestination::FlushLogFiles(min_severity); -} - -void FlushLogFilesUnsafe(LogSeverity min_severity) { - LogDestination::FlushLogFilesUnsafe(min_severity); -} - -void SetLogDestination(LogSeverity severity, const char* base_filename) { - LogDestination::SetLogDestination(severity, base_filename); -} - -void SetLogSymlink(LogSeverity severity, const char* symlink_basename) { - LogDestination::SetLogSymlink(severity, symlink_basename); -} - -LogSink::~LogSink() { -} - -void LogSink::WaitTillSent() { - // noop default -} - -string LogSink::ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len, int32 usecs) { - ostringstream stream(string(message, message_len)); - stream.fill('0'); - - stream << LogSeverityNames[severity][0] - << setw(4) << 1900+tm_time->tm_year - << setw(2) << 1+tm_time->tm_mon - << setw(2) << tm_time->tm_mday - << ' ' - << setw(2) << tm_time->tm_hour << ':' - << setw(2) << tm_time->tm_min << ':' - << setw(2) << tm_time->tm_sec << '.' - << setw(6) << usecs - << ' ' - << setfill(' ') << setw(5) << GetTID() << setfill('0') - << ' ' - << file << ':' << line << "] "; - - stream << string(message, message_len); - return stream.str(); -} - -void AddLogSink(LogSink *destination) { - LogDestination::AddLogSink(destination); -} - -void RemoveLogSink(LogSink *destination) { - LogDestination::RemoveLogSink(destination); -} - -void SetLogFilenameExtension(const char* ext) { - LogDestination::SetLogFilenameExtension(ext); -} - -void SetStderrLogging(LogSeverity min_severity) { - LogDestination::SetStderrLogging(min_severity); -} - -void SetEmailLogging(LogSeverity min_severity, const char* addresses) { - LogDestination::SetEmailLogging(min_severity, addresses); -} - -void LogToStderr() { - LogDestination::LogToStderr(); -} - -namespace base { -namespace internal { - -bool GetExitOnDFatal(); -bool GetExitOnDFatal() { - MutexLock l(&log_mutex); - return exit_on_dfatal; -} - -// Determines whether we exit the program for a LOG(DFATAL) message in -// debug mode. It does this by skipping the call to Fail/FailQuietly. -// This is intended for testing only. -// -// This can have some effects on LOG(FATAL) as well. Failure messages -// are always allocated (rather than sharing a buffer), the crash -// reason is not recorded, the "gwq" status message is not updated, -// and the stack trace is not recorded. The LOG(FATAL) *will* still -// exit the program. Since this function is used only in testing, -// these differences are acceptable. -void SetExitOnDFatal(bool value); -void SetExitOnDFatal(bool value) { - MutexLock l(&log_mutex); - exit_on_dfatal = value; -} - -} // namespace internal -} // namespace base - -// Shell-escaping as we need to shell out ot /bin/mail. -static const char kDontNeedShellEscapeChars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+-_.=/:,@"; - -static string ShellEscape(const string& src) { - string result; - if (!src.empty() && // empty string needs quotes - src.find_first_not_of(kDontNeedShellEscapeChars) == string::npos) { - // only contains chars that don't need quotes; it's fine - result.assign(src); - } else if (src.find_first_of('\'') == string::npos) { - // no single quotes; just wrap it in single quotes - result.assign("'"); - result.append(src); - result.append("'"); - } else { - // needs double quote escaping - result.assign("\""); - for (size_t i = 0; i < src.size(); ++i) { - switch (src[i]) { - case '\\': - case '$': - case '"': - case '`': - result.append("\\"); - } - result.append(src, i, 1); - } - result.append("\""); - } - return result; -} - - -// use_logging controls whether the logging functions LOG/VLOG are used -// to log errors. It should be set to false when the caller holds the -// log_mutex. -static bool SendEmailInternal(const char*dest, const char *subject, - const char*body, bool use_logging) { - if (dest && *dest) { - if ( use_logging ) { - VLOG(1) << "Trying to send TITLE:" << subject - << " BODY:" << body << " to " << dest; - } else { - fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n", - subject, body, dest); - } - - string cmd = - FLAGS_logmailer + " -s" + - ShellEscape(subject) + " " + ShellEscape(dest); - VLOG(4) << "Mailing command: " << cmd; - - FILE* pipe = popen(cmd.c_str(), "w"); - if (pipe != NULL) { - // Add the body if we have one - if (body) - fwrite(body, sizeof(char), strlen(body), pipe); - bool ok = pclose(pipe) != -1; - if ( !ok ) { - if ( use_logging ) { - LOG(ERROR) << "Problems sending mail to " << dest << ": " - << StrError(errno); - } else { - fprintf(stderr, "Problems sending mail to %s: %s\n", - dest, StrError(errno).c_str()); - } - } - return ok; - } else { - if ( use_logging ) { - LOG(ERROR) << "Unable to send mail to " << dest; - } else { - fprintf(stderr, "Unable to send mail to %s\n", dest); - } - } - } - return false; -} - -bool SendEmail(const char*dest, const char *subject, const char*body){ - return SendEmailInternal(dest, subject, body, true); -} - -static void GetTempDirectories(vector<string>* list) { - list->clear(); -#ifdef OS_WINDOWS - // On windows we'll try to find a directory in this order: - // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is) - // C:/TMP/ - // C:/TEMP/ - // C:/WINDOWS/ or C:/WINNT/ - // . - char tmp[MAX_PATH]; - if (GetTempPathA(MAX_PATH, tmp)) - list->push_back(tmp); - list->push_back("C:\\tmp\\"); - list->push_back("C:\\temp\\"); -#else - // Directories, in order of preference. If we find a dir that - // exists, we stop adding other less-preferred dirs - const char * candidates[] = { - // Non-null only during unittest/regtest - getenv("TEST_TMPDIR"), - - // Explicitly-supplied temp dirs - getenv("TMPDIR"), getenv("TMP"), - - // If all else fails - "/tmp", - }; - - for (size_t i = 0; i < ARRAYSIZE(candidates); i++) { - const char *d = candidates[i]; - if (!d) continue; // Empty env var - - // Make sure we don't surprise anyone who's expecting a '/' - string dstr = d; - if (dstr[dstr.size() - 1] != '/') { - dstr += "/"; - } - list->push_back(dstr); - - struct stat statbuf; - if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) { - // We found a dir that exists - we're done. - return; - } - } - -#endif -} - -static vector<string>* logging_directories_list; - -const vector<string>& GetLoggingDirectories() { - // Not strictly thread-safe but we're called early in InitGoogle(). - if (logging_directories_list == NULL) { - logging_directories_list = new vector<string>; - - if ( !FLAGS_log_dir.empty() ) { - // A dir was specified, we should use it - logging_directories_list->push_back(FLAGS_log_dir.c_str()); - } else { - GetTempDirectories(logging_directories_list); -#ifdef OS_WINDOWS - char tmp[MAX_PATH]; - if (GetWindowsDirectoryA(tmp, MAX_PATH)) - logging_directories_list->push_back(tmp); - logging_directories_list->push_back(".\\"); -#else - logging_directories_list->push_back("./"); -#endif - } - } - return *logging_directories_list; -} - -void TestOnly_ClearLoggingDirectoriesList() { - fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " - "called from test code.\n"); - delete logging_directories_list; - logging_directories_list = NULL; -} - -void GetExistingTempDirectories(vector<string>* list) { - GetTempDirectories(list); - vector<string>::iterator i_dir = list->begin(); - while( i_dir != list->end() ) { - // zero arg to access means test for existence; no constant - // defined on windows - if ( access(i_dir->c_str(), 0) ) { - i_dir = list->erase(i_dir); - } else { - ++i_dir; - } - } -} - -void TruncateLogFile(const char *path, int64 limit, int64 keep) { -#ifdef HAVE_UNISTD_H - struct stat statbuf; - const int kCopyBlockSize = 8 << 10; - char copybuf[kCopyBlockSize]; - int64 read_offset, write_offset; - // Don't follow symlinks unless they're our own fd symlinks in /proc - int flags = O_RDWR; - // TODO(hamaji): Support other environments. -#ifdef OS_LINUX - const char *procfd_prefix = "/proc/self/fd/"; - if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; -#endif - - int fd = open(path, flags); - if (fd == -1) { - if (errno == EFBIG) { - // The log file in question has got too big for us to open. The - // real fix for this would be to compile logging.cc (or probably - // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's - // rather scary. - // Instead just truncate the file to something we can manage - if (truncate(path, 0) == -1) { - PLOG(ERROR) << "Unable to truncate " << path; - } else { - LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; - } - } else { - PLOG(ERROR) << "Unable to open " << path; - } - return; - } - - if (fstat(fd, &statbuf) == -1) { - PLOG(ERROR) << "Unable to fstat()"; - goto out_close_fd; - } - - // See if the path refers to a regular file bigger than the - // specified limit - if (!S_ISREG(statbuf.st_mode)) goto out_close_fd; - if (statbuf.st_size <= limit) goto out_close_fd; - if (statbuf.st_size <= keep) goto out_close_fd; - - // This log file is too large - we need to truncate it - LOG(INFO) << "Truncating " << path << " to " << keep << " bytes"; - - // Copy the last "keep" bytes of the file to the beginning of the file - read_offset = statbuf.st_size - keep; - write_offset = 0; - int bytesin, bytesout; - while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { - bytesout = pwrite(fd, copybuf, bytesin, write_offset); - if (bytesout == -1) { - PLOG(ERROR) << "Unable to write to " << path; - break; - } else if (bytesout != bytesin) { - LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout; - } - read_offset += bytesin; - write_offset += bytesout; - } - if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path; - - // Truncate the remainder of the file. If someone else writes to the - // end of the file after our last read() above, we lose their latest - // data. Too bad ... - if (ftruncate(fd, write_offset) == -1) { - PLOG(ERROR) << "Unable to truncate " << path; - } - - out_close_fd: - close(fd); -#else - LOG(ERROR) << "No log truncation support."; -#endif -} - -void TruncateStdoutStderr() { -#ifdef HAVE_UNISTD_H - int64 limit = MaxLogSize() << 20; - int64 keep = 1 << 20; - TruncateLogFile("/proc/self/fd/1", limit, keep); - TruncateLogFile("/proc/self/fd/2", limit, keep); -#else - LOG(ERROR) << "No log truncation support."; -#endif -} - - -// Helper functions for string comparisons. -#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ - string* Check##func##expected##Impl(const char* s1, const char* s2, \ - const char* names) { \ - bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ - if (equal == expected) return NULL; \ - else { \ - ostringstream ss; \ - if (!s1) s1 = ""; \ - if (!s2) s2 = ""; \ - ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ - return new string(ss.str()); \ - } \ - } -DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) -DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) -DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) -DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) -#undef DEFINE_CHECK_STROP_IMPL - -int posix_strerror_r(int err, char *buf, size_t len) { - // Sanity check input parameters - if (buf == NULL || len <= 0) { - errno = EINVAL; - return -1; - } - - // Reset buf and errno, and try calling whatever version of strerror_r() - // is implemented by glibc - buf[0] = '\000'; - int old_errno = errno; - errno = 0; - char *rc = reinterpret_cast<char *>(strerror_r(err, buf, len)); - - // Both versions set errno on failure - if (errno) { - // Should already be there, but better safe than sorry - buf[0] = '\000'; - return -1; - } - errno = old_errno; - - // POSIX is vague about whether the string will be terminated, although - // is indirectly implies that typically ERANGE will be returned, instead - // of truncating the string. This is different from the GNU implementation. - // We play it safe by always terminating the string explicitly. - buf[len-1] = '\000'; - - // If the function succeeded, we can use its exit code to determine the - // semantics implemented by glibc - if (!rc) { - return 0; - } else { - // GNU semantics detected - if (rc == buf) { - return 0; - } else { - buf[0] = '\000'; -#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) - if (reinterpret_cast<intptr_t>(rc) < sys_nerr) { - // This means an error on MacOSX or FreeBSD. - return -1; - } -#endif - strncat(buf, rc, len-1); - return 0; - } - } -} - -string StrError(int err) { - char buf[100]; - int rc = posix_strerror_r(err, buf, sizeof(buf)); - if ((rc < 0) || (buf[0] == '\000')) { - snprintf(buf, sizeof(buf), "Error number %d", err); - } - return buf; -} - -LogMessageFatal::LogMessageFatal(const char* file, int line) : - LogMessage(file, line, GLOG_FATAL) {} - -LogMessageFatal::LogMessageFatal(const char* file, int line, - const CheckOpString& result) : - LogMessage(file, line, result) {} - -LogMessageFatal::~LogMessageFatal() { - Flush(); - LogMessage::Fail(); -} - -namespace base { - -CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext) - : stream_(new ostringstream) { - *stream_ << exprtext << " ("; -} - -CheckOpMessageBuilder::~CheckOpMessageBuilder() { - delete stream_; -} - -ostream* CheckOpMessageBuilder::ForVar2() { - *stream_ << " vs. "; - return stream_; -} - -string* CheckOpMessageBuilder::NewString() { - *stream_ << ")"; - return new string(stream_->str()); -} - -} // namespace base - -template <> -void MakeCheckOpValueString(std::ostream* os, const char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "char value " << (short)v; - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const signed char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "signed char value " << (short)v; - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "unsigned char value " << (unsigned short)v; - } -} - -void InitGoogleLogging(const char* argv0) { - glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); -} - -void ShutdownGoogleLogging() { - glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); - LogDestination::DeleteLogDestinations(); - delete logging_directories_list; - logging_directories_list = NULL; -} - -void EnableLogCleaner(int overdue_days) { - log_cleaner_enabled_ = true; - - // Setting overdue_days to 0 day should not be allowed! - // Since all logs will be deleted immediately, which will cause troubles. - if (overdue_days > 0) { - log_cleaner_overdue_days_ = overdue_days; - } -} - -void DisableLogCleaner() { - log_cleaner_enabled_ = false; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/logging_striplog_test.sh b/third_party/glog/src/logging_striplog_test.sh deleted file mode 100755 index 73492bda7a77..000000000000 --- a/third_party/glog/src/logging_striplog_test.sh +++ /dev/null @@ -1,79 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 2007, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Author: Sergey Ioffe - -get_strings () { - if test -e ".libs/$1"; then - binary=".libs/$1" - elif test -e "$1.exe"; then - binary="$1.exe" - else - echo "We coundn't find $1 binary." - exit 1 - fi - - strings -n 10 $binary | sort | awk '/TESTMESSAGE/ {printf "%s ", $2}' -} - -# Die if "$1" != "$2", print $3 as death reason -check_eq () { - if [ "$1" != "$2" ]; then - echo "Check failed: '$1' == '$2' ${3:+ ($3)}" - exit 1 - fi -} - -die () { - echo $1 - exit 1 -} - -# Check that the string literals are appropriately stripped. This will -# not be the case in debug mode. - -mode=`GLOG_check_mode=1 ./logging_striptest0 2> /dev/null` -if [ "$mode" = "opt" ]; -then - echo "In OPT mode" - check_eq "`get_strings logging_striptest0`" "COND ERROR FATAL INFO USAGE WARNING " - check_eq "`get_strings logging_striptest2`" "COND ERROR FATAL USAGE " - check_eq "`get_strings logging_striptest10`" "" -else - echo "In DBG mode; not checking strings" -fi - -# Check that LOG(FATAL) aborts even for large STRIP_LOG - -./logging_striptest2 2>/dev/null && die "Did not abort for STRIP_LOG=2" -./logging_striptest10 2>/dev/null && die "Did not abort for STRIP_LOG=10" - -echo "PASS" diff --git a/third_party/glog/src/logging_striptest10.cc b/third_party/glog/src/logging_striptest10.cc deleted file mode 100644 index f6e1078f39a2..000000000000 --- a/third_party/glog/src/logging_striptest10.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Sergey Ioffe - -#define GOOGLE_STRIP_LOG 10 - -// Include the actual test. -#include "logging_striptest_main.cc" diff --git a/third_party/glog/src/logging_striptest2.cc b/third_party/glog/src/logging_striptest2.cc deleted file mode 100644 index a64685c9e5cd..000000000000 --- a/third_party/glog/src/logging_striptest2.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Sergey Ioffe - -#define GOOGLE_STRIP_LOG 2 - -// Include the actual test. -#include "logging_striptest_main.cc" diff --git a/third_party/glog/src/logging_striptest_main.cc b/third_party/glog/src/logging_striptest_main.cc deleted file mode 100644 index 2fb91272a7b1..000000000000 --- a/third_party/glog/src/logging_striptest_main.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Sergey Ioffe - -// The common part of the striplog tests. - -#include <stdio.h> -#include <string> -#include <iosfwd> -#include "glog/logging.h" -#include "base/commandlineflags.h" -#include "config.h" - -DECLARE_bool(logtostderr); -GLOG_DEFINE_bool(check_mode, false, "Prints 'opt' or 'dbg'"); - -using std::string; -using namespace GOOGLE_NAMESPACE; - -int CheckNoReturn(bool b) { - string s; - if (b) { - LOG(FATAL) << "Fatal"; - } else { - return 0; - } -} - -struct A { }; -std::ostream &operator<<(std::ostream &str, const A&) {return str;} - -int main(int, char* argv[]) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - if (FLAGS_check_mode) { - printf("%s\n", DEBUG_MODE ? "dbg" : "opt"); - return 0; - } - LOG(INFO) << "TESTMESSAGE INFO"; - LOG(WARNING) << 2 << "something" << "TESTMESSAGE WARNING" - << 1 << 'c' << A() << std::endl; - LOG(ERROR) << "TESTMESSAGE ERROR"; - bool flag = true; - (flag ? LOG(INFO) : LOG(ERROR)) << "TESTMESSAGE COND"; - LOG(FATAL) << "TESTMESSAGE FATAL"; -} diff --git a/third_party/glog/src/logging_unittest.cc b/third_party/glog/src/logging_unittest.cc deleted file mode 100644 index 73d426b878d7..000000000000 --- a/third_party/glog/src/logging_unittest.cc +++ /dev/null @@ -1,1348 +0,0 @@ -// Copyright (c) 2002, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Ray Sidney - -#include "config_for_unittests.h" -#include "utilities.h" - -#include <fcntl.h> -#ifdef HAVE_GLOB_H -# include <glob.h> -#endif -#include <sys/stat.h> -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -#ifdef HAVE_SYS_WAIT_H -# include <sys/wait.h> -#endif - -#include <iomanip> -#include <iostream> -#include <fstream> -#include <memory> -#include <queue> -#include <sstream> -#include <string> -#include <vector> - -#include <stdio.h> -#include <stdlib.h> - -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "googletest.h" - -DECLARE_string(log_backtrace_at); // logging.cc - -#ifdef HAVE_LIB_GFLAGS -#include <gflags/gflags.h> -using namespace GFLAGS_NAMESPACE; -#endif - -#ifdef HAVE_LIB_GMOCK -#include <gmock/gmock.h> -#include "mock-log.h" -// Introduce several symbols from gmock. -using testing::_; -using testing::AnyNumber; -using testing::HasSubstr; -using testing::AllOf; -using testing::StrNe; -using testing::StrictMock; -using testing::InitGoogleMock; -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -#endif - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -// Some non-advertised functions that we want to test or use. -_START_GOOGLE_NAMESPACE_ -namespace base { -namespace internal { -bool GetExitOnDFatal(); -void SetExitOnDFatal(bool value); -} // namespace internal -} // namespace base -_END_GOOGLE_NAMESPACE_ - -static void TestLogging(bool check_counts); -static void TestRawLogging(); -static void LogWithLevels(int v, int severity, bool err, bool alsoerr); -static void TestLoggingLevels(); -static void TestLogString(); -static void TestLogSink(); -static void TestLogToString(); -static void TestLogSinkWaitTillSent(); -static void TestCHECK(); -static void TestDCHECK(); -static void TestSTREQ(); -static void TestBasename(); -static void TestBasenameAppendWhenNoTimestamp(); -static void TestTwoProcessesWrite(); -static void TestSymlink(); -static void TestExtension(); -static void TestWrapper(); -static void TestErrno(); -static void TestTruncate(); -static void TestCustomLoggerDeletionOnShutdown(); - -static int x = -1; -static void BM_Check1(int n) { - while (n-- > 0) { - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - } -} -BENCHMARK(BM_Check1); - -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"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - } -} -BENCHMARK(BM_Check3); - -static void BM_Check2(int n) { - if (n == 17) { - x = 5; - } - while (n-- > 0) { - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - } -} -BENCHMARK(BM_Check2); - -static void CheckFailure(int, int, const char* /* file */, int /* line */, - const char* /* msg */) { -} - -static void BM_logspeed(int n) { - while (n-- > 0) { - LOG(INFO) << "test message"; - } -} -BENCHMARK(BM_logspeed); - -static void BM_vlog(int n) { - while (n-- > 0) { - VLOG(1) << "test message"; - } -} -BENCHMARK(BM_vlog); - -int main(int argc, char **argv) { - FLAGS_colorlogtostderr = false; - FLAGS_timestamp_in_logfile_name = true; -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#endif - // Make sure stderr is not buffered as stderr seems to be buffered - // on recent windows. - setbuf(stderr, NULL); - - // Test some basics before InitGoogleLogging: - CaptureTestStderr(); - LogWithLevels(FLAGS_v, FLAGS_stderrthreshold, - FLAGS_logtostderr, FLAGS_alsologtostderr); - LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors" - const string early_stderr = GetCapturedTestStderr(); - - InitGoogleLogging(argv[0]); - - RunSpecifiedBenchmarks(); - - FLAGS_logtostderr = true; - - InitGoogleTest(&argc, argv); -#ifdef HAVE_LIB_GMOCK - InitGoogleMock(&argc, argv); -#endif - - // so that death tests run before we use threads - CHECK_EQ(RUN_ALL_TESTS(), 0); - - CaptureTestStderr(); - - // re-emit early_stderr - LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr; - - TestLogging(true); - TestRawLogging(); - TestLoggingLevels(); - TestLogString(); - TestLogSink(); - TestLogToString(); - TestLogSinkWaitTillSent(); - TestCHECK(); - TestDCHECK(); - TestSTREQ(); - - // TODO: The golden test portion of this test is very flakey. - EXPECT_TRUE( - MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err")); - - FLAGS_logtostderr = false; - - TestBasename(); - TestBasenameAppendWhenNoTimestamp(); - TestTwoProcessesWrite(); - TestSymlink(); - TestExtension(); - TestWrapper(); - TestErrno(); - TestTruncate(); - TestCustomLoggerDeletionOnShutdown(); - - fprintf(stdout, "PASS\n"); - return 0; -} - -void TestLogging(bool check_counts) { - 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); - - LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4; - for ( int i = 0; i < 10; ++i ) { - int old_errno = errno; - errno = i; - PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER; - errno = old_errno; - - LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl; - LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl; - - LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER; - LOG_IF_EVERY_N(WARNING, false, 3) - << "Log if every 3, iteration " << COUNTER; - LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER; - LOG_IF_EVERY_N(ERROR, (i < 3), 2) - << "Log if less than 3 every 2, iteration " << COUNTER; - } - LOG_IF(WARNING, true) << "log_if this"; - LOG_IF(WARNING, false) << "don't log_if this"; - - char s[] = "array"; - LOG(INFO) << s; - const char const_s[] = "const array"; - LOG(INFO) << const_s; - int j = 1000; - LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " " - << setw(1) << hex << j; - - { - google::LogMessage outer(__FILE__, __LINE__, GLOG_ERROR); - outer.stream() << "outer"; - - LOG(ERROR) << "inner"; - } - - LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix"; - - if (check_counts) { - CHECK_EQ(base_num_infos + 14, 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"; -} - -struct NewHook { - NewHook() { - g_new_hook = &NoAllocNewHook; - } - ~NewHook() { - g_new_hook = NULL; - } -}; - -TEST(DeathNoAllocNewHook, logging) { - // tests that NewHook used below works - NewHook new_hook; - ASSERT_DEATH({ - new int; - }, "unexpected new"); -} - -void TestRawLogging() { - string* foo = new string("foo "); - string huge_str(50000, 'a'); - - FlagSaver saver; - - // Check that RAW loggging does not use mallocs. - NewHook new_hook; - - RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4); - char s[] = "array"; - RAW_LOG(WARNING, "%s", s); - const char const_s[] = "const array"; - RAW_LOG(INFO, "%s", const_s); - void* p = reinterpret_cast<void*>(PTR_TEST_VALUE); - RAW_LOG(INFO, "ptr %p", p); - p = NULL; - RAW_LOG(INFO, "ptr %p", p); - int j = 1000; - RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j); - RAW_VLOG(0, "foo %d", j); - -#ifdef NDEBUG - RAW_LOG(INFO, "foo %d", j); // so that have same stderr to compare -#else - RAW_DLOG(INFO, "foo %d", j); // test RAW_DLOG in debug mode -#endif - - // test how long messages are chopped: - RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str()); - RAW_VLOG(0, "Huge string: %s", huge_str.c_str()); - - FLAGS_v = 0; - RAW_LOG(INFO, "log"); - RAW_VLOG(0, "vlog 0 on"); - RAW_VLOG(1, "vlog 1 off"); - RAW_VLOG(2, "vlog 2 off"); - RAW_VLOG(3, "vlog 3 off"); - FLAGS_v = 2; - RAW_LOG(INFO, "log"); - RAW_VLOG(1, "vlog 1 on"); - RAW_VLOG(2, "vlog 2 on"); - RAW_VLOG(3, "vlog 3 off"); - -#ifdef NDEBUG - RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode"); -#endif - - RAW_CHECK(1 == 1, "should be ok"); - RAW_DCHECK(true, "should be ok"); - - delete foo; -} - -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); - - FlagSaver saver; - - FLAGS_v = v; - FLAGS_stderrthreshold = severity; - FLAGS_logtostderr = err; - FLAGS_alsologtostderr = alsoerr; - - RAW_VLOG(-1, "vlog -1"); - RAW_VLOG(0, "vlog 0"); - RAW_VLOG(1, "vlog 1"); - RAW_LOG(INFO, "log info"); - RAW_LOG(WARNING, "log warning"); - RAW_LOG(ERROR, "log error"); - - VLOG(-1) << "vlog -1"; - VLOG(0) << "vlog 0"; - VLOG(1) << "vlog 1"; - LOG(INFO) << "log info"; - LOG(WARNING) << "log warning"; - LOG(ERROR) << "log error"; - - VLOG_IF(-1, true) << "vlog_if -1"; - VLOG_IF(-1, false) << "don't vlog_if -1"; - VLOG_IF(0, true) << "vlog_if 0"; - VLOG_IF(0, false) << "don't vlog_if 0"; - VLOG_IF(1, true) << "vlog_if 1"; - VLOG_IF(1, false) << "don't vlog_if 1"; - LOG_IF(INFO, true) << "log_if info"; - LOG_IF(INFO, false) << "don't log_if info"; - LOG_IF(WARNING, true) << "log_if warning"; - LOG_IF(WARNING, false) << "don't log_if warning"; - LOG_IF(ERROR, true) << "log_if error"; - 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 = 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"; - EXPECT_EQ(c, -1); - 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"; - EXPECT_EQ(c, 0); - 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"; - EXPECT_EQ(c, 1); - 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"; - EXPECT_EQ(c, 0); -} - -void TestLoggingLevels() { - LogWithLevels(0, GLOG_INFO, false, false); - LogWithLevels(1, GLOG_INFO, false, false); - LogWithLevels(-1, GLOG_INFO, false, false); - LogWithLevels(0, GLOG_WARNING, false, false); - LogWithLevels(0, GLOG_ERROR, false, false); - LogWithLevels(0, GLOG_FATAL, false, false); - LogWithLevels(0, GLOG_FATAL, true, false); - LogWithLevels(0, GLOG_FATAL, false, true); - LogWithLevels(1, GLOG_WARNING, false, false); - LogWithLevels(1, GLOG_FATAL, false, true); -} - -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"); -} - -void TestLogString() { - vector<string> errors; - vector<string> *no_errors = NULL; - - 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(ERROR, NULL) << "LOG_STRING: " << "reported error"; - - for (size_t i = 0; i < errors.size(); ++i) { - LOG(INFO) << "Captured by LOG_STRING: " << errors[i]; - } -} - -void TestLogToString() { - string error; - string* no_error = NULL; - - 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(INFO) << "Captured by LOG_TO_STRING: " << 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(ERROR, NULL) << "LOG_TO_STRING: " << "reported error"; -} - -class TestLogSinkImpl : public LogSink { - public: - vector<string> errors; - virtual void send(LogSeverity severity, const char* /* full_filename */, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len, int usecs) { - errors.push_back( - ToString(severity, base_filename, line, tm_time, message, message_len, usecs)); - } - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) { - send(severity, full_filename, base_filename, line, - tm_time, message, message_len, 0); - } -}; - -void TestLogSink() { - TestLogSinkImpl sink; - LogSink *no_sink = NULL; - - 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(NULL, 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(&sink, 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(no_sink, 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(NULL, ERROR) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error"; - - LOG(INFO) << "Captured by LOG_TO_SINK:"; - for (size_t i = 0; i < sink.errors.size(); ++i) { - LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() - << sink.errors[i]; - } -} - -// For testing using CHECK*() on anonymous enums. -enum { - CASE_A, - CASE_B -}; - -void TestCHECK() { - // Tests using CHECK*() on int values. - CHECK(1 == 1); - CHECK_EQ(1, 1); - CHECK_NE(1, 2); - CHECK_GE(1, 1); - CHECK_GE(2, 1); - CHECK_LE(1, 1); - CHECK_LE(1, 2); - CHECK_GT(2, 1); - CHECK_LT(1, 2); - - // Tests using CHECK*() on anonymous enums. - // Apple's GCC doesn't like this. -#if !defined(OS_MACOSX) - CHECK_EQ(CASE_A, CASE_A); - CHECK_NE(CASE_A, CASE_B); - CHECK_GE(CASE_A, CASE_A); - CHECK_GE(CASE_B, CASE_A); - CHECK_LE(CASE_A, CASE_A); - CHECK_LE(CASE_A, CASE_B); - CHECK_GT(CASE_B, CASE_A); - CHECK_LT(CASE_A, CASE_B); -#endif -} - -void TestDCHECK() { -#ifdef NDEBUG - DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode"; -#endif - DCHECK( 1 == 1 ); - DCHECK_EQ(1, 1); - DCHECK_NE(1, 2); - DCHECK_GE(1, 1); - DCHECK_GE(2, 1); - DCHECK_LE(1, 1); - DCHECK_LE(1, 2); - DCHECK_GT(2, 1); - DCHECK_LT(1, 2); - - int64* orig_ptr = new int64; - int64* ptr = DCHECK_NOTNULL(orig_ptr); - CHECK_EQ(ptr, orig_ptr); - delete orig_ptr; -} - -void TestSTREQ() { - CHECK_STREQ("this", "this"); - CHECK_STREQ(NULL, NULL); - CHECK_STRCASEEQ("this", "tHiS"); - CHECK_STRCASEEQ(NULL, NULL); - CHECK_STRNE("this", "tHiS"); - CHECK_STRNE("this", NULL); - CHECK_STRCASENE("this", "that"); - CHECK_STRCASENE(NULL, "that"); - CHECK_STREQ((string("a")+"b").c_str(), "ab"); - CHECK_STREQ(string("test").c_str(), - (string("te") + string("st")).c_str()); -} - -TEST(DeathSTREQ, logging) { - ASSERT_DEATH(CHECK_STREQ(NULL, "this"), ""); - ASSERT_DEATH(CHECK_STREQ("this", "siht"), ""); - ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), ""); - ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), ""); - ASSERT_DEATH(CHECK_STRNE(NULL, NULL), ""); - ASSERT_DEATH(CHECK_STRNE("this", "this"), ""); - 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); - 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)); -} - -TEST(DeathCheckNN, Simple) { - ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), ""); -} - -// Get list of file names that match pattern -static void GetFiles(const string& pattern, vector<string>* files) { - files->clear(); -#if defined(HAVE_GLOB_H) - glob_t g; - const int r = glob(pattern.c_str(), 0, NULL, &g); - CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern; - for (size_t i = 0; i < g.gl_pathc; i++) { - files->push_back(string(g.gl_pathv[i])); - } - globfree(&g); -#elif defined(OS_WINDOWS) - WIN32_FIND_DATAA data; - HANDLE handle = FindFirstFileA(pattern.c_str(), &data); - size_t index = pattern.rfind('\\'); - if (index == string::npos) { - LOG(FATAL) << "No directory separator."; - } - const string dirname = pattern.substr(0, index + 1); - if (handle == INVALID_HANDLE_VALUE) { - // Finding no files is OK. - return; - } - do { - files->push_back(dirname + data.cFileName); - } while (FindNextFileA(handle, &data)); - BOOL result = FindClose(handle); - LOG_SYSRESULT(result); -#else -# error There is no way to do glob. -#endif -} - -// Delete files patching pattern -static void DeleteFiles(const string& pattern) { - vector<string> files; - GetFiles(pattern, &files); - for (size_t i = 0; i < files.size(); i++) { - CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno); - } -} - -//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); - - FILE* file = fopen(files[0].c_str(), "r"); - CHECK(file != NULL) << ": could not open " << files[0]; - char buf[1000]; - while (fgets(buf, sizeof(buf), file) != NULL) { - char* first = strstr(buf, expected_string.c_str()); - //if first == NULL, not found. - //Terser than if (checkInFileOrNot && first != NULL || !check... - if (checkInFileOrNot != (first == NULL)) { - fclose(file); - return; - } - } - fclose(file); - LOG(FATAL) << "Did " << (checkInFileOrNot? "not " : "") << "find " << expected_string << " in " << files[0]; -} - -static void TestBasename() { - fprintf(stderr, "==== Test setting log file basename\n"); - const string dest = FLAGS_test_tmpdir + "/logging_test_basename"; - DeleteFiles(dest + "*"); - - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new base"; - FlushLogFiles(GLOG_INFO); - - CheckFile(dest, "message to new base"); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -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"; - DeleteFiles(dest + "*"); - - ofstream out(dest.c_str()); - out << "test preexisting content" << endl; - out.close(); - - CheckFile(dest, "test preexisting content"); - - 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; - - //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"); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -static void TestTwoProcessesWrite() { -// 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"; - DeleteFiles(dest + "*"); - - //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); - - 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 - exit(0); - } else if (pid > 0) { - wait(NULL); - } - 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); - - // Release - LogToStderr(); - DeleteFiles(dest + "*"); -#endif -} - -static void TestSymlink() { -#ifndef OS_WINDOWS - fprintf(stderr, "==== Test setting log file symlink\n"); - string dest = FLAGS_test_tmpdir + "/logging_test_symlink"; - string sym = FLAGS_test_tmpdir + "/symlinkbase"; - DeleteFiles(dest + "*"); - DeleteFiles(sym + "*"); - - SetLogSymlink(GLOG_INFO, "symlinkbase"); - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new symlink"; - FlushLogFiles(GLOG_INFO); - CheckFile(sym, "message to new symlink"); - - DeleteFiles(dest + "*"); - DeleteFiles(sym + "*"); -#endif -} - -static void TestExtension() { - fprintf(stderr, "==== Test setting log file extension\n"); - string dest = FLAGS_test_tmpdir + "/logging_test_extension"; - DeleteFiles(dest + "*"); - - SetLogDestination(GLOG_INFO, dest.c_str()); - SetLogFilenameExtension("specialextension"); - LOG(INFO) << "message to new extension"; - FlushLogFiles(GLOG_INFO); - CheckFile(dest, "message to new extension"); - - // Check that file name ends with extension - vector<string> filenames; - GetFiles(dest + "*", &filenames); - CHECK_EQ(filenames.size(), 1UL); - CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -struct MyLogger : public base::Logger { - string data; - - virtual void Write(bool /* should_flush */, - time_t /* timestamp */, - const char* message, - int length) { - data.append(message, length); - } - - virtual void Flush() { } - - virtual uint32 LogSize() { return data.length(); } -}; - -static void TestWrapper() { - fprintf(stderr, "==== Test log wrapper\n"); - - MyLogger my_logger; - base::Logger* old_logger = base::GetLogger(GLOG_INFO); - base::SetLogger(GLOG_INFO, &my_logger); - LOG(INFO) << "Send to wrapped logger"; - FlushLogFiles(GLOG_INFO); - base::SetLogger(GLOG_INFO, old_logger); - - CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL); -} - -static void TestErrno() { - fprintf(stderr, "==== Test errno preservation\n"); - - errno = ENOENT; - TestLogging(false); - CHECK_EQ(errno, ENOENT); -} - -static void TestOneTruncate(const char *path, int64 limit, int64 keep, - int64 dsize, int64 ksize, int64 expect) { - int fd; - CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)); - - const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!"; - const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr); - - // Fill the file with the requested data; first discard data, then kept data - int64 written = 0; - while (written < dsize) { - int bytes = min<int64>(dsize - written, discard_size); - CHECK_ERR(write(fd, discardstr, bytes)); - written += bytes; - } - written = 0; - while (written < ksize) { - int bytes = min<int64>(ksize - written, keep_size); - CHECK_ERR(write(fd, keepstr, bytes)); - written += bytes; - } - - TruncateLogFile(path, limit, keep); - - // File should now be shorter - struct stat statbuf; - CHECK_ERR(fstat(fd, &statbuf)); - CHECK_EQ(statbuf.st_size, expect); - CHECK_ERR(lseek(fd, 0, SEEK_SET)); - - // File should contain the suffix of the original file - const size_t buf_size = statbuf.st_size + 1; - char* buf = new char[buf_size]; - memset(buf, 0, buf_size); - CHECK_ERR(read(fd, buf, buf_size)); - - const char *p = buf; - int64 checked = 0; - while (checked < expect) { - int bytes = min<int64>(expect - checked, keep_size); - CHECK(!memcmp(p, keepstr, bytes)); - checked += bytes; - } - close(fd); - delete[] buf; -} - -static void TestTruncate() { -#ifdef HAVE_UNISTD_H - fprintf(stderr, "==== Test log truncation\n"); - string path = FLAGS_test_tmpdir + "/truncatefile"; - - // Test on a small file - TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10); - - // And a big file (multiple blocks to copy) - TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10); - - // Check edge-case limits - TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20); - TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0); - TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10); - TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30); - - // 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(OS_MACOSX) && !defined(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 - - // The /proc/self path makes sense only for linux. -#if defined(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]; - snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd); - TestOneTruncate(fdpath, 10, 10, 10, 10, 10); -#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) - { - *set_on_destruction_ = false; - } - virtual ~RecordDeletionLogger() { - *set_on_destruction_ = true; - } - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - int length) { - wrapped_logger_->Write(force_flush, timestamp, message, length); - } - virtual void Flush() { wrapped_logger_->Flush(); } - virtual uint32 LogSize() { return wrapped_logger_->LogSize(); } - private: - bool* set_on_destruction_; - base::Logger* wrapped_logger_; -}; - -static void TestCustomLoggerDeletionOnShutdown() { - bool custom_logger_deleted = false; - base::SetLogger(GLOG_INFO, - new RecordDeletionLogger(&custom_logger_deleted, - base::GetLogger(GLOG_INFO))); - ShutdownGoogleLogging(); - EXPECT_TRUE(custom_logger_deleted); -} - -_START_GOOGLE_NAMESPACE_ -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_ -using glog_internal_namespace_::SafeFNMatch_; -_END_GOOGLE_NAMESPACE_ - -static bool WrapSafeFNMatch(string pattern, string str) { - pattern += "abc"; - str += "defgh"; - return SafeFNMatch_(pattern.data(), pattern.size() - 3, - str.data(), str.size() - 5); -} - -TEST(SafeFNMatch, logging) { - CHECK(WrapSafeFNMatch("foo", "foo")); - CHECK(!WrapSafeFNMatch("foo", "bar")); - CHECK(!WrapSafeFNMatch("foo", "fo")); - CHECK(!WrapSafeFNMatch("foo", "foo2")); - CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext")); - CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext")); - CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext")); - CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo")); - CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip")); - CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext")); - CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext")); - CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext")); - CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2")); - CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2")); - CHECK(WrapSafeFNMatch("ba?/*", "bar/")); - CHECK(!WrapSafeFNMatch("ba?/?", "bar/")); - CHECK(!WrapSafeFNMatch("ba?/*", "bar")); -} - -// TestWaitingLogSink will save messages here -// No lock: Accessed only by TestLogSinkWriter thread -// and after its demise by its creator. -static vector<string> global_messages; - -// helper for TestWaitingLogSink below. -// Thread that does the logic of TestWaitingLogSink -// It's free to use LOG() itself. -class TestLogSinkWriter : public Thread { - public: - - TestLogSinkWriter() : should_exit_(false) { - SetJoinable(true); - Start(); - } - - // Just buffer it (can't use LOG() here). - void Buffer(const string& message) { - mutex_.Lock(); - RAW_LOG(INFO, "Buffering"); - messages_.push(message); - mutex_.Unlock(); - RAW_LOG(INFO, "Buffered"); - } - - // Wait for the buffer to clear (can't use LOG() here). - void Wait() { - RAW_LOG(INFO, "Waiting"); - mutex_.Lock(); - while (!NoWork()) { - mutex_.Unlock(); - SleepForMilliseconds(1); - mutex_.Lock(); - } - RAW_LOG(INFO, "Waited"); - mutex_.Unlock(); - } - - // Trigger thread exit. - void Stop() { - MutexLock l(&mutex_); - should_exit_ = true; - } - - private: - - // helpers --------------- - - // For creating a "Condition". - bool NoWork() { return messages_.empty(); } - bool HaveWork() { return !messages_.empty() || should_exit_; } - - // Thread body; CAN use LOG() here! - virtual void Run() { - while (1) { - mutex_.Lock(); - while (!HaveWork()) { - mutex_.Unlock(); - SleepForMilliseconds(1); - mutex_.Lock(); - } - if (should_exit_ && messages_.empty()) { - mutex_.Unlock(); - break; - } - // Give the main thread time to log its message, - // so that we get a reliable log capture to compare to golden file. - // Same for the other sleep below. - SleepForMilliseconds(20); - RAW_LOG(INFO, "Sink got a messages"); // only RAW_LOG under mutex_ here - string message = messages_.front(); - messages_.pop(); - // Normally this would be some more real/involved logging logic - // where LOG() usage can't be eliminated, - // e.g. pushing the message over with an RPC: - int messages_left = messages_.size(); - mutex_.Unlock(); - SleepForMilliseconds(20); - // May not use LOG while holding mutex_, because Buffer() - // acquires mutex_, and Buffer is called from LOG(), - // which has its own internal mutex: - // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer() - LOG(INFO) << "Sink is sending out a message: " << message; - LOG(INFO) << "Have " << messages_left << " left"; - global_messages.push_back(message); - } - } - - // data --------------- - - Mutex mutex_; - bool should_exit_; - queue<string> messages_; // messages to be logged -}; - -// A log sink that exercises WaitTillSent: -// it pushes data to a buffer and wakes up another thread to do the logging -// (that other thread can than use LOG() itself), -class TestWaitingLogSink : public LogSink { - public: - - TestWaitingLogSink() { - tid_ = pthread_self(); // for thread-specific behavior - AddLogSink(this); - } - ~TestWaitingLogSink() { - RemoveLogSink(this); - writer_.Stop(); - writer_.Join(); - } - - // (re)define LogSink interface - - virtual void send(LogSeverity severity, const char* /* full_filename */, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len, int usecs) { - // Push it to Writer thread if we are the original logging thread. - // 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, - tm_time, message, message_len, usecs)); - } - } - - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) { - send(severity, full_filename, base_filename, line, tm_time, message, message_len); - } - - virtual void WaitTillSent() { - // Wait for Writer thread if we are the original logging thread. - if (pthread_equal(tid_, pthread_self())) writer_.Wait(); - } - - private: - - pthread_t tid_; - TestLogSinkWriter writer_; -}; - -// Check that LogSink::WaitTillSent can be used in the advertised way. -// We also do golden-stderr comparison. -static void TestLogSinkWaitTillSent() { - { 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"; - SleepForMilliseconds(60); - LOG(ERROR) << "Message 2"; - SleepForMilliseconds(60); - LOG(WARNING) << "Message 3"; - SleepForMilliseconds(60); - } - for (size_t i = 0; i < global_messages.size(); ++i) { - LOG(INFO) << "Sink capture: " << global_messages[i]; - } - CHECK_EQ(global_messages.size(), 3UL); -} - -TEST(Strerror, logging) { - int errcode = EINTR; - char *msg = strdup(strerror(errcode)); - const size_t buf_size = strlen(msg) + 1; - char *buf = new char[buf_size]; - CHECK_EQ(posix_strerror_r(errcode, NULL, 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, NULL, buf_size), -1); -#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(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); -#else - CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0); -#endif - CHECK_STREQ(buf, ""); - CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0); - CHECK_STREQ(buf, msg); - delete[] buf; - CHECK_EQ(msg, StrError(errcode)); - free(msg); -} - -// Simple routines to look at the sizes of generated code for LOG(FATAL) and -// CHECK(..) via objdump -/* -static void MyFatal() { - LOG(FATAL) << "Failed"; -} -static void MyCheck(bool a, bool b) { - CHECK_EQ(a, b); -} -*/ -#ifdef HAVE_LIB_GMOCK - -TEST(DVLog, Basic) { - ScopedMockLog log; - -#if NDEBUG - // We are expecting that nothing is logged. - EXPECT_CALL(log, Log(_, _, _)).Times(0); -#else - EXPECT_CALL(log, Log(INFO, __FILE__, "debug log")); -#endif - - FLAGS_v = 1; - DVLOG(1) << "debug log"; -} - -TEST(DVLog, V0) { - ScopedMockLog log; - - // We are expecting that nothing is logged. - EXPECT_CALL(log, Log(_, _, _)).Times(0); - - FLAGS_v = 0; - DVLOG(1) << "debug log"; -} - -TEST(LogAtLevel, Basic) { - ScopedMockLog log; - - // The function version outputs "logging.h" as a file name. - EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version")); - EXPECT_CALL(log, Log(INFO, __FILE__, "macro version")); - - int severity = WARNING; - LogAtLevel(severity, "function version"); - - severity = INFO; - // We can use the macro version as a C++ stream. - LOG_AT_LEVEL(severity) << "macro" << ' ' << "version"; -} - -TEST(TestExitOnDFatal, ToBeOrNotToBe) { - // Check the default setting... - EXPECT_TRUE(base::internal::GetExitOnDFatal()); - - // Turn off... - base::internal::SetExitOnDFatal(false); - EXPECT_FALSE(base::internal::GetExitOnDFatal()); - - // 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. - const LogSeverity severity = -#ifdef NDEBUG - ERROR; -#else - FATAL; -#endif - EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal")); - LOG(DFATAL) << "This should not be fatal"; - } - - // Turn back on... - base::internal::SetExitOnDFatal(true); - EXPECT_TRUE(base::internal::GetExitOnDFatal()); - -#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 -} - -#ifdef HAVE_STACKTRACE - -static void BacktraceAtHelper() { - LOG(INFO) << "Not me"; - -// 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 - -TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) { - StrictMock<ScopedMockLog> log; - - FLAGS_log_backtrace_at = ""; - - EXPECT_CALL(log, Log(_, _, "Backtrace me")); - EXPECT_CALL(log, Log(_, _, "Not me")); - - BacktraceAtHelper(); -} - -TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) { - StrictMock<ScopedMockLog> log; - - char where[100]; - snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine); - FLAGS_log_backtrace_at = where; - - // The LOG at the specified line should include a stacktrace which includes - // 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")))); - // Other LOGs should not include a backtrace. - EXPECT_CALL(log, Log(_, _, "Not me")); - - BacktraceAtHelper(); -} - -#endif // HAVE_STACKTRACE - -#endif // HAVE_LIB_GMOCK - -struct UserDefinedClass { - bool operator==(const UserDefinedClass&) const { return true; } -}; - -inline ostream& operator<<(ostream& out, const UserDefinedClass&) { - out << "OK"; - return out; -} - -TEST(UserDefinedClass, logging) { - UserDefinedClass u; - vector<string> buf; - LOG_STRING(INFO, &buf) << u; - CHECK_EQ(1UL, buf.size()); - CHECK(buf[0].find("OK") != string::npos); - - // We must be able to compile this. - CHECK_EQ(u, u); -} diff --git a/third_party/glog/src/logging_unittest.err b/third_party/glog/src/logging_unittest.err deleted file mode 100644 index def0e93f1e80..000000000000 --- a/third_party/glog/src/logging_unittest.err +++ /dev/null @@ -1,307 +0,0 @@ -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WARNING: Logging before InitGoogleLogging() is written to STDERR -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo bar 10 3.4 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 1 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 1 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 1 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 2 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2] -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 3 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 3 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 4 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 4 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 5 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 5 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 6 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 6 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 7 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 7 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 8 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 9 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 9 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 10 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 10 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] array -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] const array -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000 0000001000 3e8 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] inner -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] outer -no prefix -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: const array -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __PTRTEST__ -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __NULLP__ -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 on -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 on -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 2 on -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK: -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 diff --git a/third_party/glog/src/mock-log.h b/third_party/glog/src/mock-log.h deleted file mode 100644 index 30a0f74efeab..000000000000 --- a/third_party/glog/src/mock-log.h +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Zhanyong Wan -// -// Defines the ScopedMockLog class (using Google C++ Mocking -// Framework), which is convenient for testing code that uses LOG(). - -#ifndef GLOG_SRC_MOCK_LOG_H_ -#define GLOG_SRC_MOCK_LOG_H_ - -// For GOOGLE_NAMESPACE. This must go first so we get _XOPEN_SOURCE. -#include "utilities.h" - -#include <string> - -#include <gmock/gmock.h> - -#include "glog/logging.h" - -_START_GOOGLE_NAMESPACE_ -namespace glog_testing { - -// A ScopedMockLog object intercepts LOG() messages issued during its -// lifespan. Using this together with Google C++ Mocking Framework, -// it's very easy to test how a piece of code calls LOG(). The -// typical usage: -// -// TEST(FooTest, LogsCorrectly) { -// ScopedMockLog log; -// -// // We expect the WARNING "Something bad!" exactly twice. -// EXPECT_CALL(log, Log(WARNING, _, "Something bad!")) -// .Times(2); -// -// // We allow foo.cc to call LOG(INFO) any number of times. -// EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _)) -// .Times(AnyNumber()); -// -// Foo(); // Exercises the code under test. -// } -class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink { - public: - // When a ScopedMockLog object is constructed, it starts to - // intercept logs. - ScopedMockLog() { AddLogSink(this); } - - // When the object is destructed, it stops intercepting logs. - virtual ~ScopedMockLog() { RemoveLogSink(this); } - - // Implements the mock method: - // - // void Log(LogSeverity severity, const string& file_path, - // const string& message); - // - // The second argument to Send() is the full path of the source file - // in which the LOG() was issued. - // - // Note, that in a multi-threaded environment, all LOG() messages from a - // single thread will be handled in sequence, but that cannot be guaranteed - // for messages from different threads. In fact, if the same or multiple - // expectations are matched on two threads concurrently, their actions will - // be executed concurrently as well and may interleave. - MOCK_METHOD3(Log, void(GOOGLE_NAMESPACE::LogSeverity severity, - const std::string& file_path, - const std::string& message)); - - private: - // Implements the send() virtual function in class LogSink. - // Whenever a LOG() statement is executed, this function will be - // invoked with information presented in the LOG(). - // - // The method argument list is long and carries much information a - // test usually doesn't care about, so we trim the list before - // forwarding the call to Log(), which is much easier to use in - // tests. - // - // We still cannot call Log() directly, as it may invoke other LOG() - // messages, either due to Invoke, or due to an error logged in - // Google C++ Mocking Framework code, which would trigger a deadlock - // since a lock is held during send(). - // - // Hence, we save the message for WaitTillSent() which will be called after - // the lock on send() is released, and we'll call Log() inside - // WaitTillSent(). Since while a single send() call may be running at a - // time, multiple WaitTillSent() calls (along with the one send() call) may - // be running simultaneously, we ensure thread-safety of the exchange between - // send() and WaitTillSent(), and that for each message, LOG(), send(), - // WaitTillSent() and Log() are executed in the same thread. - virtual void send(GOOGLE_NAMESPACE::LogSeverity severity, - const char* full_filename, - const char* /*base_filename*/, int /*line*/, - const tm* /*tm_time*/, - const char* message, size_t message_len) { - // We are only interested in the log severity, full file name, and - // log message. - message_info_.severity = severity; - message_info_.file_path = full_filename; - message_info_.message = std::string(message, message_len); - } - - // Implements the WaitTillSent() virtual function in class LogSink. - // It will be executed after send() and after the global logging lock is - // released, so calls within it (or rather within the Log() method called - // within) may also issue LOG() statements. - // - // LOG(), send(), WaitTillSent() and Log() will occur in the same thread for - // a given log message. - virtual void WaitTillSent() { - // First, and very importantly, we save a copy of the message being - // processed before calling Log(), since Log() may indirectly call send() - // and WaitTillSent() in the same thread again. - MessageInfo message_info = message_info_; - Log(message_info.severity, message_info.file_path, message_info.message); - } - - // All relevant information about a logged message that needs to be passed - // from send() to WaitTillSent(). - struct MessageInfo { - GOOGLE_NAMESPACE::LogSeverity severity; - std::string file_path; - std::string message; - }; - MessageInfo message_info_; -}; - -} // namespace glog_testing -_END_GOOGLE_NAMESPACE_ - -#endif // GLOG_SRC_MOCK_LOG_H_ diff --git a/third_party/glog/src/mock-log_test.cc b/third_party/glog/src/mock-log_test.cc deleted file mode 100644 index 7d58a307c222..000000000000 --- a/third_party/glog/src/mock-log_test.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Zhanyong Wan - -// Tests the ScopedMockLog class. - -#include "mock-log.h" - -#include <string> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -namespace { - -using GOOGLE_NAMESPACE::INFO; -using GOOGLE_NAMESPACE::WARNING; -using GOOGLE_NAMESPACE::ERROR; -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -using std::string; -using testing::_; -using testing::HasSubstr; -using testing::InSequence; -using testing::InvokeWithoutArgs; - -// Tests that ScopedMockLog intercepts LOG()s when it's alive. -TEST(ScopedMockLogTest, InterceptsLog) { - ScopedMockLog log; - - InSequence s; - EXPECT_CALL(log, Log(WARNING, HasSubstr("/mock-log_test.cc"), "Fishy.")); - EXPECT_CALL(log, Log(INFO, _, "Working...")) - .Times(2); - EXPECT_CALL(log, Log(ERROR, _, "Bad!!")); - - LOG(WARNING) << "Fishy."; - LOG(INFO) << "Working..."; - LOG(INFO) << "Working..."; - LOG(ERROR) << "Bad!!"; -} - -void LogBranch() { - LOG(INFO) << "Logging a branch..."; -} - -void LogTree() { - LOG(INFO) << "Logging the whole tree..."; -} - -void LogForest() { - LOG(INFO) << "Logging the entire forest."; - LOG(INFO) << "Logging the entire forest.."; - LOG(INFO) << "Logging the entire forest..."; -} - -// The purpose of the following test is to verify that intercepting logging -// continues to work properly if a LOG statement is executed within the scope -// of a mocked call. -TEST(ScopedMockLogTest, LogDuringIntercept) { - ScopedMockLog log; - InSequence s; - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging a branch...")) - .WillOnce(InvokeWithoutArgs(LogTree)); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the whole tree...")) - .WillOnce(InvokeWithoutArgs(LogForest)); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest.")); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest..")); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest...")); - LogBranch(); -} - -} // namespace - -int main(int argc, char **argv) { - GOOGLE_NAMESPACE::InitGoogleLogging(argv[0]); - testing::InitGoogleMock(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/third_party/glog/src/package_config_unittest/working_config/CMakeLists.txt b/third_party/glog/src/package_config_unittest/working_config/CMakeLists.txt deleted file mode 100644 index d701aa7b1b7a..000000000000 --- a/third_party/glog/src/package_config_unittest/working_config/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required (VERSION 3.1) -project (glog_package_config) - -find_package (glog REQUIRED NO_MODULE) - -add_executable (glog_package_config glog_package_config.cc) - -target_link_libraries (glog_package_config PRIVATE glog::glog) diff --git a/third_party/glog/src/package_config_unittest/working_config/glog_package_config.cc b/third_party/glog/src/package_config_unittest/working_config/glog_package_config.cc deleted file mode 100644 index b7b5cf6c6650..000000000000 --- a/third_party/glog/src/package_config_unittest/working_config/glog_package_config.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include <glog/logging.h> - -int main(int /*argc*/, char** argv) -{ - google::InitGoogleLogging(argv[0]); -} diff --git a/third_party/glog/src/raw_logging.cc b/third_party/glog/src/raw_logging.cc deleted file mode 100644 index ba65961e9053..000000000000 --- a/third_party/glog/src/raw_logging.cc +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Maxim Lifantsev -// -// logging_unittest.cc covers the functionality herein - -#include "utilities.h" - -#include <stdarg.h> -#include <stdio.h> -#include <errno.h> -#ifdef HAVE_UNISTD_H -# include <unistd.h> // for close() and write() -#endif -#include <fcntl.h> // for open() -#include <time.h> -#include "config.h" -#include "glog/logging.h" // To pick up flag settings etc. -#include "glog/raw_logging.h" -#include "base/commandlineflags.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -#if defined(HAVE_SYSCALL_H) -#include <syscall.h> // for syscall() -#elif defined(HAVE_SYS_SYSCALL_H) -#include <sys/syscall.h> // for syscall() -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H) -# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len) -#else - // Not so safe, but what can you do? -# define safe_write(fd, s, len) write(fd, s, len) -#endif - -_START_GOOGLE_NAMESPACE_ - -// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths -// that invoke malloc() and getenv() that might acquire some locks. -// If this becomes a problem we should reimplement a subset of vsnprintf -// that does not need locks and malloc. - -// Helper for RawLog__ below. -// *DoRawLog writes to *buf of *size and move them past the written portion. -// It returns true iff there was no overflow or error. -static bool DoRawLog(char** buf, int* size, const char* format, ...) { - va_list ap; - va_start(ap, format); - int n = vsnprintf(*buf, *size, format, ap); - va_end(ap); - if (n < 0 || n > *size) return false; - *size -= n; - *buf += n; - return true; -} - -// Helper for RawLog__ below. -inline static bool VADoRawLog(char** buf, int* size, - const char* format, va_list ap) { - int n = vsnprintf(*buf, *size, format, ap); - if (n < 0 || n > *size) return false; - *size -= n; - *buf += n; - return true; -} - -static const int kLogBufSize = 3000; -static bool crashed = false; -static CrashReason crash_reason; -static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0' - -void RawLog__(LogSeverity severity, const char* file, int line, - const char* format, ...) { - if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold || - FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) { - return; // this stderr log message is suppressed - } - // can't call localtime_r here: it can allocate - char buffer[kLogBufSize]; - char* buf = buffer; - int size = sizeof(buffer); - - // NOTE: this format should match the specification in base/logging.h - DoRawLog(&buf, &size, "%c00000000 00:00:00.000000 %5u %s:%d] RAW: ", - LogSeverityNames[severity][0], - static_cast<unsigned int>(GetTID()), - const_basename(const_cast<char *>(file)), line); - - // Record the position and size of the buffer after the prefix - const char* msg_start = buf; - const int msg_size = size; - - va_list ap; - va_start(ap, format); - bool no_chop = VADoRawLog(&buf, &size, format, ap); - va_end(ap); - if (no_chop) { - DoRawLog(&buf, &size, "\n"); - } else { - DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n"); - } - // We make a raw syscall to write directly to the stderr file descriptor, - // avoiding FILE buffering (to avoid invoking malloc()), and bypassing - // libc (to side-step any libc interception). - // We write just once to avoid races with other invocations of RawLog__. - safe_write(STDERR_FILENO, buffer, strlen(buffer)); - if (severity == GLOG_FATAL) { - if (!sync_val_compare_and_swap(&crashed, false, true)) { - crash_reason.filename = file; - crash_reason.line_number = line; - memcpy(crash_buf, msg_start, msg_size); // Don't include prefix - crash_reason.message = crash_buf; -#ifdef HAVE_STACKTRACE - crash_reason.depth = - GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1); -#else - crash_reason.depth = 0; -#endif - SetCrashReason(&crash_reason); - } - LogMessage::Fail(); // abort() - } -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/signalhandler.cc b/third_party/glog/src/signalhandler.cc deleted file mode 100644 index 955471899afe..000000000000 --- a/third_party/glog/src/signalhandler.cc +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// Implementation of InstallFailureSignalHandler(). - -#include "utilities.h" -#include "stacktrace.h" -#include "symbolize.h" -#include "glog/logging.h" - -#include <signal.h> -#include <time.h> -#ifdef HAVE_UCONTEXT_H -# include <ucontext.h> -#endif -#ifdef HAVE_SYS_UCONTEXT_H -# include <sys/ucontext.h> -#endif -#include <algorithm> - -_START_GOOGLE_NAMESPACE_ - -namespace { - -// We'll install the failure signal handler for these signals. We could -// use strsignal() to get signal names, but we don't use it to avoid -// introducing yet another #ifdef complication. -// -// The list should be synced with the comment in signalhandler.h. -const struct { - int number; - const char *name; -} kFailureSignals[] = { - { SIGSEGV, "SIGSEGV" }, - { SIGILL, "SIGILL" }, - { SIGFPE, "SIGFPE" }, - { SIGABRT, "SIGABRT" }, -#if !defined(OS_WINDOWS) - { SIGBUS, "SIGBUS" }, -#endif - { SIGTERM, "SIGTERM" }, -}; - -static bool kFailureSignalHandlerInstalled = false; - -// Returns the program counter from signal context, NULL if unknown. -void* GetPC(void* ucontext_in_void) { -#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT) - if (ucontext_in_void != NULL) { - ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void); - return (void*)context->PC_FROM_UCONTEXT; - } -#endif - return NULL; -} - -// The class is used for formatting error messages. We don't use printf() -// as it's not async signal safe. -class MinimalFormatter { - public: - MinimalFormatter(char *buffer, int size) - : buffer_(buffer), - cursor_(buffer), - end_(buffer + size) { - } - - // Returns the number of bytes written in the buffer. - int num_bytes_written() const { return (int) (cursor_ - buffer_); } - - // Appends string from "str" and updates the internal cursor. - void AppendString(const char* str) { - int i = 0; - while (str[i] != '\0' && cursor_ + i < end_) { - cursor_[i] = str[i]; - ++i; - } - cursor_ += i; - } - - // Formats "number" in "radix" and updates the internal cursor. - // Lowercase letters are used for 'a' - 'z'. - void AppendUint64(uint64 number, int radix) { - int i = 0; - while (cursor_ + i < end_) { - const int tmp = number % radix; - number /= radix; - cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10); - ++i; - if (number == 0) { - break; - } - } - // Reverse the bytes written. - std::reverse(cursor_, cursor_ + i); - cursor_ += i; - } - - // Formats "number" as hexadecimal number, and updates the internal - // cursor. Padding will be added in front if needed. - void AppendHexWithPadding(uint64 number, int width) { - char* start = cursor_; - AppendString("0x"); - AppendUint64(number, 16); - // Move to right and add padding in front if needed. - if (cursor_ < start + width) { - const int64 delta = start + width - cursor_; - std::copy(start, cursor_, start + delta); - std::fill(start, start + delta, ' '); - cursor_ = start + width; - } - } - - private: - char *buffer_; - char *cursor_; - const char * const end_; -}; - -// Writes the given data with the size to the standard error. -void WriteToStderr(const char* data, int size) { - if (write(STDERR_FILENO, data, size) < 0) { - // Ignore errors. - } -} - -// The writer function can be changed by InstallFailureWriter(). -void (*g_failure_writer)(const char* data, int size) = WriteToStderr; - -// Dumps time information. We don't dump human-readable time information -// as localtime() is not guaranteed to be async signal safe. -void DumpTimeInfo() { - time_t time_in_sec = time(NULL); - char buf[256]; // Big enough for time info. - MinimalFormatter formatter(buf, sizeof(buf)); - formatter.AppendString("*** Aborted at "); - formatter.AppendUint64(time_in_sec, 10); - formatter.AppendString(" (unix time)"); - formatter.AppendString(" try \"date -d @"); - formatter.AppendUint64(time_in_sec, 10); - formatter.AppendString("\" if you are using GNU date ***\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -// TODO(hamaji): Use signal instead of sigaction? -#ifdef HAVE_SIGACTION - -// Dumps information about the signal to STDERR. -void DumpSignalInfo(int signal_number, siginfo_t *siginfo) { - // Get the signal name. - const char* signal_name = NULL; - for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { - if (signal_number == kFailureSignals[i].number) { - signal_name = kFailureSignals[i].name; - } - } - - char buf[256]; // Big enough for signal info. - MinimalFormatter formatter(buf, sizeof(buf)); - - formatter.AppendString("*** "); - if (signal_name) { - formatter.AppendString(signal_name); - } else { - // Use the signal number if the name is unknown. The signal name - // should be known, but just in case. - formatter.AppendString("Signal "); - formatter.AppendUint64(signal_number, 10); - } - formatter.AppendString(" (@0x"); - formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16); - formatter.AppendString(")"); - formatter.AppendString(" received by PID "); - formatter.AppendUint64(getpid(), 10); - formatter.AppendString(" (TID 0x"); - // We assume pthread_t is an integral number or a pointer, rather - // than a complex struct. In some environments, pthread_self() - // returns an uint64 but in some other environments pthread_self() - // returns a pointer. Hence we use C-style cast here, rather than - // reinterpret/static_cast, to support both types of environments. - formatter.AppendUint64((uintptr_t)pthread_self(), 16); - formatter.AppendString(") "); - // Only linux has the PID of the signal sender in si_pid. -#ifdef OS_LINUX - formatter.AppendString("from PID "); - formatter.AppendUint64(siginfo->si_pid, 10); - formatter.AppendString("; "); -#endif - formatter.AppendString("stack trace: ***\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -#endif // HAVE_SIGACTION - -// Dumps information about the stack frame to STDERR. -void DumpStackFrameInfo(const char* prefix, void* pc) { - // Get the symbol name. - const char *symbol = "(unknown)"; - char symbolized[1024]; // Big enough for a sane symbol. - // Symbolizes the previous address of pc because pc may be in the - // next function. - if (Symbolize(reinterpret_cast<char *>(pc) - 1, - symbolized, sizeof(symbolized))) { - symbol = symbolized; - } - - char buf[1024]; // Big enough for stack frame info. - MinimalFormatter formatter(buf, sizeof(buf)); - - formatter.AppendString(prefix); - formatter.AppendString("@ "); - const int width = 2 * sizeof(void*) + 2; // + 2 for "0x". - formatter.AppendHexWithPadding(reinterpret_cast<uintptr_t>(pc), width); - formatter.AppendString(" "); - formatter.AppendString(symbol); - formatter.AppendString("\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -// Invoke the default signal handler. -void InvokeDefaultSignalHandler(int signal_number) { -#ifdef HAVE_SIGACTION - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_handler = SIG_DFL; - sigaction(signal_number, &sig_action, NULL); - kill(getpid(), signal_number); -#elif defined(OS_WINDOWS) - signal(signal_number, SIG_DFL); - raise(signal_number); -#endif -} - -// This variable is used for protecting FailureSignalHandler() from -// dumping stuff while another thread is doing it. Our policy is to let -// the first thread dump stuff and let other threads wait. -// See also comments in FailureSignalHandler(). -static pthread_t* g_entered_thread_id_pointer = NULL; - -// Dumps signal and stack frame information, and invokes the default -// signal handler once our job is done. -#if defined(OS_WINDOWS) -void FailureSignalHandler(int signal_number) -#else -void FailureSignalHandler(int signal_number, - siginfo_t *signal_info, - void *ucontext) -#endif -{ - // First check if we've already entered the function. We use an atomic - // compare and swap operation for platforms that support it. For other - // platforms, we use a naive method that could lead to a subtle race. - - // We assume pthread_self() is async signal safe, though it's not - // officially guaranteed. - pthread_t my_thread_id = pthread_self(); - // NOTE: We could simply use pthread_t rather than pthread_t* for this, - // if pthread_self() is guaranteed to return non-zero value for thread - // ids, but there is no such guarantee. We need to distinguish if the - // old value (value returned from __sync_val_compare_and_swap) is - // different from the original value (in this case NULL). - pthread_t* old_thread_id_pointer = - glog_internal_namespace_::sync_val_compare_and_swap( - &g_entered_thread_id_pointer, - static_cast<pthread_t*>(NULL), - &my_thread_id); - if (old_thread_id_pointer != NULL) { - // We've already entered the signal handler. What should we do? - if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) { - // It looks the current thread is reentering the signal handler. - // Something must be going wrong (maybe we are reentering by another - // type of signal?). Kill ourself by the default signal handler. - InvokeDefaultSignalHandler(signal_number); - } - // Another thread is dumping stuff. Let's wait until that thread - // finishes the job and kills the process. - while (true) { - sleep(1); - } - } - // This is the first time we enter the signal handler. We are going to - // do some interesting stuff from here. - // TODO(satorux): We might want to set timeout here using alarm(), but - // mixing alarm() and sleep() can be a bad idea. - - // First dump time info. - DumpTimeInfo(); - -#if !defined(OS_WINDOWS) - // Get the program counter from ucontext. - void *pc = GetPC(ucontext); - DumpStackFrameInfo("PC: ", pc); -#endif - -#ifdef HAVE_STACKTRACE - // Get the stack traces. - void *stack[32]; - // +1 to exclude this function. - const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1); -# ifdef HAVE_SIGACTION - DumpSignalInfo(signal_number, signal_info); -# endif - // Dump the stack traces. - for (int i = 0; i < depth; ++i) { - DumpStackFrameInfo(" ", stack[i]); - } -#endif - - // *** TRANSITION *** - // - // BEFORE this point, all code must be async-termination-safe! - // (See WARNING above.) - // - // AFTER this point, we do unsafe things, like using LOG()! - // The process could be terminated or hung at any time. We try to - // do more useful things first and riskier things later. - - // Flush the logs before we do anything in case 'anything' - // causes problems. - FlushLogFilesUnsafe(0); - - // Kill ourself by the default signal handler. - InvokeDefaultSignalHandler(signal_number); -} - -} // namespace - -namespace glog_internal_namespace_ { - -bool IsFailureSignalHandlerInstalled() { -#ifdef HAVE_SIGACTION - // TODO(andschwa): Return kFailureSignalHandlerInstalled? - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sigaction(SIGABRT, NULL, &sig_action); - if (sig_action.sa_sigaction == &FailureSignalHandler) - return true; -#elif defined(OS_WINDOWS) - return kFailureSignalHandlerInstalled; -#endif // HAVE_SIGACTION - return false; -} - -} // namespace glog_internal_namespace_ - -void InstallFailureSignalHandler() { -#ifdef HAVE_SIGACTION - // Build the sigaction struct. - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_flags |= SA_SIGINFO; - sig_action.sa_sigaction = &FailureSignalHandler; - - for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { - CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL)); - } - kFailureSignalHandlerInstalled = true; -#elif defined(OS_WINDOWS) - for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { - CHECK_NE(signal(kFailureSignals[i].number, &FailureSignalHandler), - SIG_ERR); - } - kFailureSignalHandlerInstalled = true; -#endif // HAVE_SIGACTION -} - -void InstallFailureWriter(void (*writer)(const char* data, int size)) { -#if defined(HAVE_SIGACTION) || defined(OS_WINDOWS) - g_failure_writer = writer; -#endif // HAVE_SIGACTION -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/signalhandler_unittest.cc b/third_party/glog/src/signalhandler_unittest.cc deleted file mode 100644 index 36d957b9c353..000000000000 --- a/third_party/glog/src/signalhandler_unittest.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// This is a helper binary for testing signalhandler.cc. The actual test -// is done in signalhandler_unittest.sh. - -#include "utilities.h" - -#if defined(HAVE_PTHREAD) -# include <pthread.h> -#endif -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string> -#include "glog/logging.h" - -#ifdef HAVE_LIB_GFLAGS -#include <gflags/gflags.h> -using namespace GFLAGS_NAMESPACE; -#endif - -using namespace GOOGLE_NAMESPACE; - -static void* DieInThread(void*) { - // We assume pthread_t is an integral number or a pointer, rather - // than a complex struct. In some environments, pthread_self() - // returns an uint64 but in some other environments pthread_self() - // returns a pointer. Hence we use C-style cast here, rather than - // reinterpret/static_cast, to support both types of environments. - fprintf(stderr, "0x%lx is dying\n", (long)pthread_self()); - // Use volatile to prevent from these to be optimized away. - volatile int a = 0; - volatile int b = 1 / a; - fprintf(stderr, "We should have died: b=%d\n", b); - return NULL; -} - -static void WriteToStdout(const char* data, int size) { - if (write(STDOUT_FILENO, data, size) < 0) { - // Ignore errors. - } -} - -int main(int argc, char **argv) { -#if defined(HAVE_STACKTRACE) && defined(HAVE_SYMBOLIZE) - InitGoogleLogging(argv[0]); -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#endif - InstallFailureSignalHandler(); - const std::string command = argc > 1 ? argv[1] : "none"; - if (command == "segv") { - // We'll check if this is outputted. - LOG(INFO) << "create the log file"; - LOG(INFO) << "a message before segv"; - // We assume 0xDEAD is not writable. - int *a = (int*)0xDEAD; - *a = 0; - } else if (command == "loop") { - fprintf(stderr, "looping\n"); - while (true); - } else if (command == "die_in_thread") { -#if defined(HAVE_PTHREAD) - pthread_t thread; - pthread_create(&thread, NULL, &DieInThread, NULL); - pthread_join(thread, NULL); -#else - fprintf(stderr, "no pthread\n"); - return 1; -#endif - } else if (command == "dump_to_stdout") { - InstallFailureWriter(WriteToStdout); - abort(); - } else if (command == "installed") { - fprintf(stderr, "signal handler installed: %s\n", - IsFailureSignalHandlerInstalled() ? "true" : "false"); - } else { - // Tell the shell script - puts("OK"); - } -#endif - return 0; -} diff --git a/third_party/glog/src/signalhandler_unittest.sh b/third_party/glog/src/signalhandler_unittest.sh deleted file mode 100755 index 265cd458c01e..000000000000 --- a/third_party/glog/src/signalhandler_unittest.sh +++ /dev/null @@ -1,131 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Author: Satoru Takabayashi -# -# Unit tests for signalhandler.cc. - -die () { - echo $1 - exit 1 -} - -BINDIR=".libs" -LIBGLOG="$BINDIR/libglog.so" - -BINARY="$BINDIR/signalhandler_unittest" -LOG_INFO="./signalhandler_unittest.INFO" - -# Remove temporary files. -rm -f signalhandler.out* - -if test -e "$BINARY"; then - # We need shared object. - export LD_LIBRARY_PATH=$BINDIR - export DYLD_LIBRARY_PATH=$BINDIR -else - # For windows - BINARY="./signalhandler_unittest.exe" - if ! test -e "$BINARY"; then - echo "We coundn't find demangle_unittest binary." - exit 1 - fi -fi - -if [ x`$BINARY` != 'xOK' ]; then - echo "PASS (No stacktrace support. We don't run this test.)" - exit 0 -fi - -# The PC cannot be obtained in signal handlers on PowerPC correctly. -# We just skip the test for PowerPC. -if [ x`uname -p` = x"powerpc" ]; then - echo "PASS (We don't test the signal handler on PowerPC.)" - exit 0 -fi - -# Test for a case the program kills itself by SIGSEGV. -GOOGLE_LOG_DIR=. $BINARY segv 2> signalhandler.out1 -for pattern in SIGSEGV 0xdead main "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out1; then - die "'$pattern' should appear in the output" - fi -done -if ! grep --quiet "a message before segv" $LOG_INFO; then - die "'a message before segv' should appear in the INFO log" -fi -rm -f $LOG_INFO - -# Test for a case the program is killed by this shell script. -# $! = the process id of the last command run in the background. -# $$ = the process id of this shell. -$BINARY loop 2> signalhandler.out2 & -# Wait until "looping" is written in the file. This indicates the program -# is ready to accept signals. -while true; do - if grep --quiet looping signalhandler.out2; then - break - fi -done -kill -TERM $! -wait $! - -from_pid='' -# Only linux has the process ID of the signal sender. -if [ x`uname` = "xLinux" ]; then - from_pid="from PID $$" -fi -for pattern in SIGTERM "by PID $!" "$from_pid" main "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out2; then - die "'$pattern' should appear in the output" - fi -done - -# Test for a case the program dies in a non-main thread. -$BINARY die_in_thread 2> signalhandler.out3 -EXPECTED_TID="`sed 's/ .*//; q' signalhandler.out3`" - -for pattern in SIGFPE DieInThread "TID $EXPECTED_TID" "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out3; then - die "'$pattern' should appear in the output" - fi -done - -# Test for a case the program installs a custom failure writer that writes -# stuff to stdout instead of stderr. -$BINARY dump_to_stdout 1> signalhandler.out4 -for pattern in SIGABRT main "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out4; then - die "'$pattern' should appear in the output" - fi -done - -echo PASS diff --git a/third_party/glog/src/stacktrace.h b/third_party/glog/src/stacktrace.h deleted file mode 100644 index cb64b33a688e..000000000000 --- a/third_party/glog/src/stacktrace.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2000 - 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Routines to extract the current stack trace. These functions are -// thread-safe. - -#ifndef BASE_STACKTRACE_H_ -#define BASE_STACKTRACE_H_ - -#include "config.h" -#include "glog/logging.h" - -_START_GOOGLE_NAMESPACE_ - -// This is similar to the GetStackFrames routine, except that it returns -// the stack trace only, and not the stack frame sizes as well. -// Example: -// main() { foo(); } -// foo() { bar(); } -// bar() { -// void* result[10]; -// int depth = GetStackFrames(result, 10, 1); -// } -// -// This produces: -// result[0] foo -// result[1] main -// .... ... -// -// "result" must not be NULL. -GOOGLE_GLOG_DLL_DECL int GetStackTrace(void** result, int max_depth, int skip_count); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_STACKTRACE_H_ diff --git a/third_party/glog/src/stacktrace_generic-inl.h b/third_party/glog/src/stacktrace_generic-inl.h deleted file mode 100644 index fad81d3e3f4f..000000000000 --- a/third_party/glog/src/stacktrace_generic-inl.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2000 - 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Portable implementation - just use glibc -// -// Note: The glibc implementation may cause a call to malloc. -// This can cause a deadlock in HeapProfiler. -#include <execinfo.h> -#include <string.h> -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - static const int kStackLength = 64; - void * stack[kStackLength]; - int size; - - size = backtrace(stack, kStackLength); - skip_count++; // we want to skip the current frame as well - int result_count = size - skip_count; - if (result_count < 0) - result_count = 0; - if (result_count > max_depth) - result_count = max_depth; - for (int i = 0; i < result_count; i++) - result[i] = stack[i + skip_count]; - - return result_count; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_libunwind-inl.h b/third_party/glog/src/stacktrace_libunwind-inl.h deleted file mode 100644 index e29a50c004f2..000000000000 --- a/third_party/glog/src/stacktrace_libunwind-inl.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2005 - 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Arun Sharma -// -// Produce stack trace using libunwind - -#include "utilities.h" - -extern "C" { -#define UNW_LOCAL_ONLY -#include <libunwind.h> -} -#include "glog/raw_logging.h" -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// Sometimes, we can try to get a stack trace from within a stack -// trace, because libunwind can call mmap (maybe indirectly via an -// internal mmap based memory allocator), and that mmap gets trapped -// and causes a stack-trace request. If were to try to honor that -// recursive request, we'd end up with infinite recursion or deadlock. -// Luckily, it's safe to ignore those subsequent traces. In such -// cases, we return 0 to indicate the situation. -// We can use the GCC __thread syntax here since libunwind is not supported on -// Windows. -static __thread bool g_tl_entered; // Initialized to false. - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - void *ip; - int n = 0; - unw_cursor_t cursor; - unw_context_t uc; - - if (g_tl_entered) { - return 0; - } - g_tl_entered = true; - - unw_getcontext(&uc); - RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed"); - skip_count++; // Do not include the "GetStackTrace" frame - - while (n < max_depth) { - int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip); - if (ret < 0) - break; - if (skip_count > 0) { - skip_count--; - } else { - result[n++] = ip; - } - ret = unw_step(&cursor); - if (ret <= 0) - break; - } - - g_tl_entered = false; - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_powerpc-inl.h b/third_party/glog/src/stacktrace_powerpc-inl.h deleted file mode 100644 index 03b91089aada..000000000000 --- a/third_party/glog/src/stacktrace_powerpc-inl.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Craig Silverstein -// -// Produce stack trace. I'm guessing (hoping!) the code is much like -// for x86. For apple machines, at least, it seems to be; see -// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html -// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK -// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 - -#include <stdio.h> -#include <stdint.h> // for uintptr_t -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// Given a pointer to a stack frame, locate and return the calling -// stackframe, or return NULL if no stackframe can be found. Perform sanity -// checks (the strictness of which is controlled by the boolean parameter -// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. -template<bool STRICT_UNWINDING> -static void **NextStackFrame(void **old_sp) { - void **new_sp = (void **) *old_sp; - - // Check that the transition from frame pointer old_sp to frame - // pointer new_sp isn't clearly bogus - if (STRICT_UNWINDING) { - // With the stack growing downwards, older stack frame must be - // at a greater address that the current one. - if (new_sp <= old_sp) return NULL; - // Assume stack frames larger than 100,000 bytes are bogus. - if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; - } else { - // In the non-strict mode, allow discontiguous stack frames. - // (alternate-signal-stacks for example). - if (new_sp == old_sp) return NULL; - // And allow frames upto about 1MB. - if ((new_sp > old_sp) - && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; - } - if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; - return new_sp; -} - -// This ensures that GetStackTrace stes up the Link Register properly. -void StacktracePowerPCDummyFunction() __attribute__((noinline)); -void StacktracePowerPCDummyFunction() { __asm__ volatile(""); } - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - void **sp; - // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther) - // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a - // different asm syntax. I don't know quite the best way to discriminate - // systems using the old as from the new one; I've gone with __APPLE__. -#ifdef __APPLE__ - __asm__ volatile ("mr %0,r1" : "=r" (sp)); -#else - __asm__ volatile ("mr %0,1" : "=r" (sp)); -#endif - - // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack - // entry that holds the return address of the subroutine call (what - // instruction we run after our function finishes). This is the - // same as the stack-pointer of our parent routine, which is what we - // want here. While the compiler will always(?) set up LR for - // subroutine calls, it may not for leaf functions (such as this one). - // This routine forces the compiler (at least gcc) to push it anyway. - StacktracePowerPCDummyFunction(); - - // The LR save area is used by the callee, so the top entry is bogus. - skip_count++; - - int n = 0; - while (sp && n < max_depth) { - if (skip_count > 0) { - skip_count--; - } else { - // PowerPC has 3 main ABIs, which say where in the stack the - // Link Register is. For DARWIN and AIX (used by apple and - // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc), - // it's in sp[1]. -#if defined(_CALL_AIX) || defined(_CALL_DARWIN) - result[n++] = *(sp+2); -#elif defined(_CALL_SYSV) - result[n++] = *(sp+1); -#elif defined(__APPLE__) || ((defined(__linux) || defined(__linux__)) && defined(__PPC64__)) - // This check is in case the compiler doesn't define _CALL_AIX/etc. - result[n++] = *(sp+2); -#elif defined(__linux) - // This check is in case the compiler doesn't define _CALL_SYSV. - result[n++] = *(sp+1); -#else -#error Need to specify the PPC ABI for your archiecture. -#endif - } - // Use strict unwinding rules. - sp = NextStackFrame<true>(sp); - } - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_unittest.cc b/third_party/glog/src/stacktrace_unittest.cc deleted file mode 100644 index 77d34291b381..000000000000 --- a/third_party/glog/src/stacktrace_unittest.cc +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (c) 2004, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "utilities.h" - -#include <stdio.h> -#include <stdlib.h> -#include "config.h" -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "stacktrace.h" - -#ifdef HAVE_EXECINFO_H -# include <execinfo.h> -#endif - -using namespace GOOGLE_NAMESPACE; - -#ifdef HAVE_STACKTRACE - -// Obtain a backtrace, verify that the expected callers are present in the -// backtrace, and maybe print the backtrace to stdout. - -// The sequence of functions whose return addresses we expect to see in the -// backtrace. -const int BACKTRACE_STEPS = 6; - -struct AddressRange { - const void *start, *end; -}; - -// Expected function [start,end] range. -AddressRange expected_range[BACKTRACE_STEPS]; - -#if __GNUC__ -// Using GCC extension: address of a label can be taken with '&&label'. -// Start should be a label somewhere before recursive call, end somewhere -// after it. -#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \ - do { \ - (prange)->start = &&start_label; \ - (prange)->end = &&end_label; \ - CHECK_LT((prange)->start, (prange)->end); \ - } while (0) -// This macro expands into "unmovable" code (opaque to GCC), and that -// prevents GCC from moving a_label up or down in the code. -// Without it, there is no code following the 'end' label, and GCC -// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before -// the recursive call. -#define DECLARE_ADDRESS_LABEL(a_label) \ - a_label: do { __asm__ __volatile__(""); } while (0) -// Gcc 4.4.0 may split function into multiple chunks, and the chunk -// performing recursive call may end up later in the code then the return -// instruction (this actually happens with FDO). -// Adjust function range from __builtin_return_address. -#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) \ - do { \ - void *ra = __builtin_return_address(0); \ - CHECK_LT((prange)->start, ra); \ - if (ra > (prange)->end) { \ - printf("Adjusting range from %p..%p to %p..%p\n", \ - (prange)->start, (prange)->end, \ - (prange)->start, ra); \ - (prange)->end = ra; \ - } \ - } while (0) -#else -// Assume the Check* functions below are not longer than 256 bytes. -#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \ - do { \ - (prange)->start = reinterpret_cast<const void *>(&fn); \ - (prange)->end = reinterpret_cast<const char *>(&fn) + 256; \ - } while (0) -#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0) -#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0) -#endif // __GNUC__ - -//-----------------------------------------------------------------------// - -static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range) -{ - CHECK_GE(ret_addr, range.start); - CHECK_LE(ret_addr, range.end); -} - -//-----------------------------------------------------------------------// - -void ATTRIBUTE_NOINLINE CheckStackTrace(int); -static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) { - const int STACK_LEN = 10; - void *stack[STACK_LEN]; - int size; - - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]); - INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]); - DECLARE_ADDRESS_LABEL(start); - size = GetStackTrace(stack, STACK_LEN, 0); - printf("Obtained %d stack frames.\n", size); - CHECK_GE(size, 1); - CHECK_LE(size, STACK_LEN); - - if (1) { -#ifdef HAVE_EXECINFO_H - char **strings = backtrace_symbols(stack, size); - printf("Obtained %d stack frames.\n", size); - for (int i = 0; i < size; i++) - printf("%s %p\n", strings[i], stack[i]); - printf("CheckStackTrace() addr: %p\n", &CheckStackTrace); - free(strings); -#endif - } - for (int i = 0; i < BACKTRACE_STEPS; i++) { - printf("Backtrace %d: expected: %p..%p actual: %p ... ", - i, expected_range[i].start, expected_range[i].end, stack[i]); - fflush(stdout); - CheckRetAddrIsInFunction(stack[i], expected_range[i]); - printf("OK\n"); - } - DECLARE_ADDRESS_LABEL(end); -} - -//-----------------------------------------------------------------------// - -/* Dummy functions to make the backtrace more interesting. */ -static void ATTRIBUTE_NOINLINE CheckStackTrace4(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]); - INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTraceLeaf(); - DECLARE_ADDRESS_LABEL(end); -} -static void ATTRIBUTE_NOINLINE CheckStackTrace3(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]); - INIT_ADDRESS_RANGE(CheckStackTrace3, start, end, &expected_range[2]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace4(j); - DECLARE_ADDRESS_LABEL(end); -} -static void ATTRIBUTE_NOINLINE CheckStackTrace2(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]); - INIT_ADDRESS_RANGE(CheckStackTrace2, start, end, &expected_range[3]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace3(j); - DECLARE_ADDRESS_LABEL(end); -} -static void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]); - INIT_ADDRESS_RANGE(CheckStackTrace1, start, end, &expected_range[4]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace2(j); - DECLARE_ADDRESS_LABEL(end); -} -#ifndef __GNUC__ -// On non-GNU environment, we use the address of `CheckStackTrace` to -// guess the address range of this function. This guess is wrong for -// non-static function on Windows. This is probably because -// `&CheckStackTrace` returns the address of a trampoline like PLT, -// not the actual address of `CheckStackTrace`. -// See https://github.com/google/glog/issues/421 for the detail. -static -#endif -void ATTRIBUTE_NOINLINE CheckStackTrace(int i) { - INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace1(j); - DECLARE_ADDRESS_LABEL(end); -} - -//-----------------------------------------------------------------------// - -int main(int, char ** argv) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - - CheckStackTrace(0); - - printf("PASS\n"); - return 0; -} - -#else -int main() { - printf("PASS (no stacktrace support)\n"); - return 0; -} -#endif // HAVE_STACKTRACE diff --git a/third_party/glog/src/stacktrace_windows-inl.h b/third_party/glog/src/stacktrace_windows-inl.h deleted file mode 100644 index f7553a6d9736..000000000000 --- a/third_party/glog/src/stacktrace_windows-inl.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2000 - 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Andrew Schwartzmeyer -// -// Windows implementation - just use CaptureStackBackTrace - -#include "config.h" -#include "port.h" -#include "stacktrace.h" -#include <dbghelp.h> - -_START_GOOGLE_NAMESPACE_ - -int GetStackTrace(void** result, int max_depth, int skip_count) { - if (max_depth > 64) { - max_depth = 64; - } - skip_count++; // we want to skip the current frame as well - // This API is thread-safe (moreover it walks only the current thread). - return CaptureStackBackTrace(skip_count, max_depth, result, NULL); -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_x86-inl.h b/third_party/glog/src/stacktrace_x86-inl.h deleted file mode 100644 index 3b8d5a8282d5..000000000000 --- a/third_party/glog/src/stacktrace_x86-inl.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) 2000 - 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Produce stack trace - -#include <stdint.h> // for uintptr_t - -#include "utilities.h" // for OS_* macros - -#if !defined(OS_WINDOWS) -#include <unistd.h> -#include <sys/mman.h> -#endif - -#include <stdio.h> // for NULL -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// Given a pointer to a stack frame, locate and return the calling -// stackframe, or return NULL if no stackframe can be found. Perform sanity -// checks (the strictness of which is controlled by the boolean parameter -// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. -template<bool STRICT_UNWINDING> -static void **NextStackFrame(void **old_sp) { - void **new_sp = (void **) *old_sp; - - // Check that the transition from frame pointer old_sp to frame - // pointer new_sp isn't clearly bogus - if (STRICT_UNWINDING) { - // With the stack growing downwards, older stack frame must be - // at a greater address that the current one. - if (new_sp <= old_sp) return NULL; - // Assume stack frames larger than 100,000 bytes are bogus. - if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; - } else { - // In the non-strict mode, allow discontiguous stack frames. - // (alternate-signal-stacks for example). - if (new_sp == old_sp) return NULL; - // And allow frames upto about 1MB. - if ((new_sp > old_sp) - && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; - } - if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; -#ifdef __i386__ - // On 64-bit machines, the stack pointer can be very close to - // 0xffffffff, so we explicitly check for a pointer into the - // last two pages in the address space - if ((uintptr_t)new_sp >= 0xffffe000) return NULL; -#endif -#if !defined(OS_WINDOWS) - if (!STRICT_UNWINDING) { - // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test - // on AMD-based machines with VDSO-enabled kernels. - // Make an extra sanity check to insure new_sp is readable. - // Note: NextStackFrame<false>() is only called while the program - // is already on its last leg, so it's ok to be slow here. - static int page_size = getpagesize(); - void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1)); - if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1) - return NULL; - } -#endif - return new_sp; -} - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - void **sp; - -#ifdef __GNUC__ -#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402 -#define USE_BUILTIN_FRAME_ADDRESS -#endif -#endif - -#ifdef USE_BUILTIN_FRAME_ADDRESS - sp = reinterpret_cast<void**>(__builtin_frame_address(0)); -#elif defined(__i386__) - // Stack frame format: - // sp[0] pointer to previous frame - // sp[1] caller address - // sp[2] first argument - // ... - sp = (void **)&result - 2; -#elif defined(__x86_64__) - // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8 - unsigned long rbp; - // Move the value of the register %rbp into the local variable rbp. - // We need 'volatile' to prevent this instruction from getting moved - // around during optimization to before function prologue is done. - // An alternative way to achieve this - // would be (before this __asm__ instruction) to call Noop() defined as - // static void Noop() __attribute__ ((noinline)); // prevent inlining - // static void Noop() { asm(""); } // prevent optimizing-away - __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp)); - // Arguments are passed in registers on x86-64, so we can't just - // offset from &result - sp = (void **) rbp; -#endif - - int n = 0; - while (sp && n < max_depth) { - if (*(sp+1) == (void *)0) { - // In 64-bit code, we often see a frame that - // points to itself and has a return address of 0. - break; - } - if (skip_count > 0) { - skip_count--; - } else { - result[n++] = *(sp+1); - } - // Use strict unwinding rules. - sp = NextStackFrame<true>(sp); - } - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_x86_64-inl.h b/third_party/glog/src/stacktrace_x86_64-inl.h deleted file mode 100644 index f7d1dca85bc1..000000000000 --- a/third_party/glog/src/stacktrace_x86_64-inl.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2005 - 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Arun Sharma -// -// Produce stack trace using libgcc - -extern "C" { -#include <stdlib.h> // for NULL -#include <unwind.h> // ABI defined unwinder -} -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -typedef struct { - void **result; - int max_depth; - int skip_count; - int count; -} trace_arg_t; - - -// Workaround for the malloc() in _Unwind_Backtrace() issue. -static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) { - return _URC_NO_REASON; -} - - -// This code is not considered ready to run until -// static initializers run so that we are guaranteed -// that any malloc-related initialization is done. -static bool ready_to_run = false; -class StackTraceInit { - public: - StackTraceInit() { - // Extra call to force initialization - _Unwind_Backtrace(nop_backtrace, NULL); - ready_to_run = true; - } -}; - -static StackTraceInit module_initializer; // Force initialization - -static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) { - trace_arg_t *targ = (trace_arg_t *) opq; - - if (targ->skip_count > 0) { - targ->skip_count--; - } else { - targ->result[targ->count++] = (void *) _Unwind_GetIP(uc); - } - - if (targ->count == targ->max_depth) - return _URC_END_OF_STACK; - - return _URC_NO_REASON; -} - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - if (!ready_to_run) - return 0; - - trace_arg_t targ; - - skip_count += 1; // Do not include the "GetStackTrace" frame - - targ.result = result; - targ.max_depth = max_depth; - targ.skip_count = skip_count; - targ.count = 0; - - _Unwind_Backtrace(GetOneFrame, &targ); - - return targ.count; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stl_logging_unittest.cc b/third_party/glog/src/stl_logging_unittest.cc deleted file mode 100644 index 269094c07bfa..000000000000 --- a/third_party/glog/src/stl_logging_unittest.cc +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2003, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "config.h" - -#ifdef HAVE_USING_OPERATOR - -#include <functional> -#include <iostream> -#include <map> -#include <ostream> -#include <string> -#include <vector> - -#ifdef __GNUC__ -// C++0x isn't enabled by default in GCC and libc++ does not have -// non-standard ext/* and tr1/unordered_*. -# if defined(_LIBCPP_VERSION) -# ifndef GLOG_STL_LOGGING_FOR_UNORDERED -# define GLOG_STL_LOGGING_FOR_UNORDERED -# endif -# else -# ifndef GLOG_STL_LOGGING_FOR_EXT_HASH -# define GLOG_STL_LOGGING_FOR_EXT_HASH -# endif -# ifndef GLOG_STL_LOGGING_FOR_EXT_SLIST -# define GLOG_STL_LOGGING_FOR_EXT_SLIST -# endif -# ifndef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# define GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# endif -# endif -#endif - -#include "glog/logging.h" -#include "glog/stl_logging.h" -#include "googletest.h" - -using namespace std; -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -using namespace __gnu_cxx; -#endif - -struct user_hash { - size_t operator()(int x) const { return x; } -}; - -static void TestSTLLogging() { - { - // Test a sequence. - vector<int> v; - v.push_back(10); - v.push_back(20); - v.push_back(30); - ostringstream ss; - ss << v; - EXPECT_EQ(ss.str(), "10 20 30"); - vector<int> copied_v(v); - CHECK_EQ(v, copied_v); // This must compile. - } - - { - // Test a sorted pair associative container. - map< int, string > m; - m[20] = "twenty"; - m[10] = "ten"; - m[30] = "thirty"; - ostringstream ss; - ss << m; - EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)"); - map< int, string > copied_m(m); - CHECK_EQ(m, copied_m); // This must compile. - } - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH - { - // Test a hashed simple associative container. - hash_set<int> hs; - hs.insert(10); - hs.insert(20); - hs.insert(30); - ostringstream ss; - ss << hs; - EXPECT_EQ(ss.str(), "10 20 30"); - hash_set<int> copied_hs(hs); - CHECK_EQ(hs, copied_hs); // This must compile. - } -#endif - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH - { - // Test a hashed pair associative container. - hash_map<int, string> hm; - hm[10] = "ten"; - hm[20] = "twenty"; - hm[30] = "thirty"; - ostringstream ss; - ss << hm; - EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)"); - hash_map<int, string> copied_hm(hm); - CHECK_EQ(hm, copied_hm); // this must compile - } -#endif - - { - // Test a long sequence. - vector<int> v; - string expected; - for (int i = 0; i < 100; i++) { - v.push_back(i); - if (i > 0) expected += ' '; - char buf[256]; - sprintf(buf, "%d", i); - expected += buf; - } - v.push_back(100); - expected += " ..."; - ostringstream ss; - ss << v; - CHECK_EQ(ss.str(), expected.c_str()); - } - - { - // Test a sorted pair associative container. - // Use a non-default comparison functor. - map< int, string, greater<int> > m; - m[20] = "twenty"; - m[10] = "ten"; - m[30] = "thirty"; - ostringstream ss; - ss << m; - EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)"); - map< int, string, greater<int> > copied_m(m); - CHECK_EQ(m, copied_m); // This must compile. - } - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH - { - // Test a hashed simple associative container. - // Use a user defined hash function. - hash_set<int, user_hash> hs; - hs.insert(10); - hs.insert(20); - hs.insert(30); - ostringstream ss; - ss << hs; - EXPECT_EQ(ss.str(), "10 20 30"); - hash_set<int, user_hash> copied_hs(hs); - CHECK_EQ(hs, copied_hs); // This must compile. - } -#endif -} - -int main(int, char**) { - TestSTLLogging(); - std::cout << "PASS\n"; - return 0; -} - -#else - -#include <iostream> - -int main(int, char**) { - std::cout << "We don't support stl_logging for this compiler.\n" - << "(we need compiler support of 'using ::operator<<' " - << "for this feature.)\n"; - return 0; -} - -#endif // HAVE_USING_OPERATOR diff --git a/third_party/glog/src/symbolize.cc b/third_party/glog/src/symbolize.cc deleted file mode 100644 index 76a1b0febeec..000000000000 --- a/third_party/glog/src/symbolize.cc +++ /dev/null @@ -1,966 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// Stack-footprint reduction work done by Raksit Ashok -// -// Implementation note: -// -// We don't use heaps but only use stacks. We want to reduce the -// stack consumption so that the symbolizer can run on small stacks. -// -// Here are some numbers collected with GCC 4.1.0 on x86: -// - sizeof(Elf32_Sym) = 16 -// - sizeof(Elf32_Shdr) = 40 -// - sizeof(Elf64_Sym) = 24 -// - sizeof(Elf64_Shdr) = 64 -// -// This implementation is intended to be async-signal-safe but uses -// some functions which are not guaranteed to be so, such as memchr() -// and memmove(). We assume they are async-signal-safe. -// -// Additional header can be specified by the GLOG_BUILD_CONFIG_INCLUDE -// macro to add platform specific defines (e.g. OS_OPENBSD). - -#ifdef GLOG_BUILD_CONFIG_INCLUDE -#include GLOG_BUILD_CONFIG_INCLUDE -#endif // GLOG_BUILD_CONFIG_INCLUDE - -#include "utilities.h" - -#if defined(HAVE_SYMBOLIZE) - -#include <string.h> - -#include <algorithm> -#include <limits> - -#include "symbolize.h" -#include "demangle.h" - -_START_GOOGLE_NAMESPACE_ - -// We don't use assert() since it's not guaranteed to be -// async-signal-safe. Instead we define a minimal assertion -// macro. So far, we don't need pretty printing for __FILE__, etc. - -// A wrapper for abort() to make it callable in ? :. -static int AssertFail() { - abort(); - return 0; // Should not reach. -} - -#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail()) - -static SymbolizeCallback g_symbolize_callback = NULL; -void InstallSymbolizeCallback(SymbolizeCallback callback) { - g_symbolize_callback = callback; -} - -static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback = - NULL; -void InstallSymbolizeOpenObjectFileCallback( - SymbolizeOpenObjectFileCallback callback) { - g_symbolize_open_object_file_callback = callback; -} - -// This function wraps the Demangle function to provide an interface -// where the input symbol is demangled in-place. -// To keep stack consumption low, we would like this function to not -// get inlined. -static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) { - char demangled[256]; // Big enough for sane demangled symbols. - if (Demangle(out, demangled, sizeof(demangled))) { - // Demangling succeeded. Copy to out if the space allows. - size_t len = strlen(demangled); - if (len + 1 <= (size_t)out_size) { // +1 for '\0'. - SAFE_ASSERT(len < sizeof(demangled)); - memmove(out, demangled, len + 1); - } - } -} - -_END_GOOGLE_NAMESPACE_ - -#if defined(__ELF__) - -#if defined(HAVE_DLFCN_H) -#include <dlfcn.h> -#endif -#if defined(OS_OPENBSD) -#include <sys/exec_elf.h> -#else -#include <elf.h> -#endif -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "symbolize.h" -#include "config.h" -#include "glog/raw_logging.h" - -// Re-runs fn until it doesn't cause EINTR. -#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR) - -_START_GOOGLE_NAMESPACE_ - -// Read up to "count" bytes from "offset" in the file pointed by file -// descriptor "fd" into the buffer starting at "buf" while handling short reads -// and EINTR. On success, return the number of bytes read. Otherwise, return -// -1. -static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count, - const off_t offset) { - SAFE_ASSERT(fd >= 0); - SAFE_ASSERT(count <= std::numeric_limits<ssize_t>::max()); - char *buf0 = reinterpret_cast<char *>(buf); - ssize_t num_bytes = 0; - while (num_bytes < count) { - ssize_t len; - NO_INTR(len = pread(fd, buf0 + num_bytes, count - num_bytes, - offset + num_bytes)); - if (len < 0) { // There was an error other than EINTR. - return -1; - } - if (len == 0) { // Reached EOF. - break; - } - num_bytes += len; - } - SAFE_ASSERT(num_bytes <= count); - return num_bytes; -} - -// Try reading exactly "count" bytes from "offset" bytes in a file -// pointed by "fd" into the buffer starting at "buf" while handling -// short reads and EINTR. On success, return true. Otherwise, return -// false. -static bool ReadFromOffsetExact(const int fd, void *buf, - const size_t count, const off_t offset) { - ssize_t len = ReadFromOffset(fd, buf, count, offset); - return len == count; -} - -// Returns elf_header.e_type if the file pointed by fd is an ELF binary. -static int FileGetElfType(const int fd) { - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return -1; - } - if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) { - return -1; - } - return elf_header.e_type; -} - -// Read the section headers in the given ELF binary, and if a section -// of the specified type is found, set the output to this section header -// and return true. Otherwise, return false. -// To keep stack consumption low, we would like this function to not get -// inlined. -static ATTRIBUTE_NOINLINE bool -GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const off_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 (int i = 0; i < sh_num;) { - const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); - const ssize_t num_bytes_to_read = - (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf); - const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read, - sh_offset + i * sizeof(buf[0])); - if (len == -1) { - return false; - } - SAFE_ASSERT(len % sizeof(buf[0]) == 0); - const ssize_t num_headers_in_buf = len / sizeof(buf[0]); - SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0])); - for (int j = 0; j < num_headers_in_buf; ++j) { - if (buf[j].sh_type == type) { - *out = buf[j]; - return true; - } - } - i += num_headers_in_buf; - } - return false; -} - -// There is no particular reason to limit section name to 63 characters, -// but there has (as yet) been no need for anything longer either. -const int kMaxSectionNameLen = 64; - -// name_len should include terminating '\0'. -bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, - ElfW(Shdr) *out) { - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return false; - } - - ElfW(Shdr) shstrtab; - off_t shstrtab_offset = (elf_header.e_shoff + - elf_header.e_shentsize * elf_header.e_shstrndx); - if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { - return false; - } - - for (int i = 0; i < elf_header.e_shnum; ++i) { - off_t section_header_offset = (elf_header.e_shoff + - elf_header.e_shentsize * i); - if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) { - return false; - } - char header_name[kMaxSectionNameLen]; - if (sizeof(header_name) < name_len) { - RAW_LOG(WARNING, "Section name '%s' is too long (%" PRIuS "); " - "section will not be found (even if present).", name, name_len); - // No point in even trying. - return false; - } - off_t name_offset = shstrtab.sh_offset + out->sh_name; - ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset); - if (n_read == -1) { - return false; - } else if (n_read != name_len) { - // Short read -- name could be at end of file. - continue; - } - if (memcmp(header_name, name, name_len) == 0) { - return true; - } - } - return false; -} - -// Read a symbol table and look for the symbol containing the -// pc. Iterate over symbols in a symbol table and look for the symbol -// containing "pc". On success, return true and write the symbol name -// to out. Otherwise, return false. -// To keep stack consumption low, we would like this function to not get -// inlined. -static ATTRIBUTE_NOINLINE bool -FindSymbol(uint64_t pc, const int fd, char *out, int out_size, - uint64_t symbol_offset, const ElfW(Shdr) *strtab, - const ElfW(Shdr) *symtab) { - if (symtab == NULL) { - return false; - } - const int num_symbols = symtab->sh_size / symtab->sh_entsize; - for (int i = 0; i < num_symbols;) { - off_t offset = symtab->sh_offset + i * symtab->sh_entsize; - - // If we are reading Elf64_Sym's, we want to limit this array to - // 32 elements (to keep stack consumption low), otherwise we can - // have a 64 element Elf32_Sym array. -#if __WORDSIZE == 64 -#define NUM_SYMBOLS 32 -#else -#define NUM_SYMBOLS 64 -#endif - - // Read at most NUM_SYMBOLS symbols at once to save read() calls. - ElfW(Sym) buf[NUM_SYMBOLS]; - int num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i); - const ssize_t len = - ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset); - SAFE_ASSERT(len % sizeof(buf[0]) == 0); - const ssize_t num_symbols_in_buf = len / sizeof(buf[0]); - SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read); - for (int j = 0; j < num_symbols_in_buf; ++j) { - const ElfW(Sym)& symbol = buf[j]; - uint64_t start_address = symbol.st_value; - start_address += symbol_offset; - uint64_t end_address = start_address + symbol.st_size; - if (symbol.st_value != 0 && // Skip null value symbols. - symbol.st_shndx != 0 && // Skip undefined symbols. - start_address <= pc && pc < end_address) { - ssize_t len1 = ReadFromOffset(fd, out, out_size, - strtab->sh_offset + symbol.st_name); - if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) { - memset(out, 0, out_size); - return false; - } - return true; // Obtained the symbol name. - } - } - i += num_symbols_in_buf; - } - return false; -} - -// Get the symbol name of "pc" from the file pointed by "fd". Process -// both regular and dynamic symbol tables if necessary. On success, -// write the symbol name to "out" and return true. Otherwise, return -// false. -static bool GetSymbolFromObjectFile(const int fd, - uint64_t pc, - char* out, - int out_size, - uint64_t base_address) { - // Read the ELF header. - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return false; - } - - ElfW(Shdr) symtab, strtab; - - // Consult a regular symbol table first. - if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, - SHT_SYMTAB, &symtab)) { - if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + - symtab.sh_link * sizeof(symtab))) { - return false; - } - if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) { - return true; // Found the symbol in a regular symbol table. - } - } - - // If the symbol is not found, then consult a dynamic symbol table. - if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, - SHT_DYNSYM, &symtab)) { - if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + - symtab.sh_link * sizeof(symtab))) { - return false; - } - if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) { - return true; // Found the symbol in a dynamic symbol table. - } - } - - return false; -} - -namespace { -// Thin wrapper around a file descriptor so that the file descriptor -// gets closed for sure. -struct FileDescriptor { - const int fd_; - explicit FileDescriptor(int fd) : fd_(fd) {} - ~FileDescriptor() { - if (fd_ >= 0) { - close(fd_); - } - } - int get() { return fd_; } - - private: - explicit FileDescriptor(const FileDescriptor&); - void operator=(const FileDescriptor&); -}; - -// Helper class for reading lines from file. -// -// Note: we don't use ProcMapsIterator since the object is big (it has -// a 5k array member) and uses async-unsafe functions such as sscanf() -// and snprintf(). -class LineReader { - public: - explicit LineReader(int fd, char *buf, int buf_len, off_t offset) - : fd_(fd), - buf_(buf), - buf_len_(buf_len), - offset_(offset), - bol_(buf), - eol_(buf), - eod_(buf) {} - - // Read '\n'-terminated line from file. On success, modify "bol" - // and "eol", then return true. Otherwise, return false. - // - // Note: if the last line doesn't end with '\n', the line will be - // dropped. It's an intentional behavior to make the code simple. - bool ReadLine(const char **bol, const char **eol) { - if (BufferIsEmpty()) { // First time. - const ssize_t num_bytes = ReadFromOffset(fd_, buf_, buf_len_, offset_); - if (num_bytes <= 0) { // EOF or error. - return false; - } - offset_ += num_bytes; - eod_ = buf_ + num_bytes; - bol_ = buf_; - } else { - bol_ = eol_ + 1; // Advance to the next line in the buffer. - SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". - if (!HasCompleteLine()) { - const int incomplete_line_length = eod_ - bol_; - // Move the trailing incomplete line to the beginning. - memmove(buf_, bol_, incomplete_line_length); - // Read text from file and append it. - char * const append_pos = buf_ + incomplete_line_length; - const int capacity_left = buf_len_ - incomplete_line_length; - const ssize_t num_bytes = - ReadFromOffset(fd_, append_pos, capacity_left, offset_); - if (num_bytes <= 0) { // EOF or error. - return false; - } - offset_ += num_bytes; - eod_ = append_pos + num_bytes; - bol_ = buf_; - } - } - eol_ = FindLineFeed(); - if (eol_ == NULL) { // '\n' not found. Malformed line. - return false; - } - *eol_ = '\0'; // Replace '\n' with '\0'. - - *bol = bol_; - *eol = eol_; - return true; - } - - // Beginning of line. - const char *bol() { - return bol_; - } - - // End of line. - const char *eol() { - return eol_; - } - - private: - explicit LineReader(const LineReader&); - void operator=(const LineReader&); - - char *FindLineFeed() { - return reinterpret_cast<char *>(memchr(bol_, '\n', eod_ - bol_)); - } - - bool BufferIsEmpty() { - return buf_ == eod_; - } - - bool HasCompleteLine() { - return !BufferIsEmpty() && FindLineFeed() != NULL; - } - - const int fd_; - char * const buf_; - const int buf_len_; - off_t offset_; - char *bol_; - char *eol_; - const char *eod_; // End of data in "buf_". -}; -} // namespace - -// Place the hex number read from "start" into "*hex". The pointer to -// the first non-hex character or "end" is returned. -static char *GetHex(const char *start, const char *end, uint64_t *hex) { - *hex = 0; - const char *p; - for (p = start; p < end; ++p) { - int ch = *p; - if ((ch >= '0' && ch <= '9') || - (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { - *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9); - } else { // Encountered the first non-hex character. - break; - } - } - SAFE_ASSERT(p <= end); - return const_cast<char *>(p); -} - -// Searches for the object file (from /proc/self/maps) that contains -// the specified pc. If found, sets |start_address| to the start address -// of where this object file is mapped in memory, sets the module base -// address into |base_address|, copies the object file name into -// |out_file_name|, and attempts to open the object file. If the object -// file is opened successfully, returns the file descriptor. Otherwise, -// returns -1. |out_file_name_size| is the size of the file name buffer -// (including the null-terminator). -static ATTRIBUTE_NOINLINE int -OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, - uint64_t &start_address, - uint64_t &base_address, - char *out_file_name, - int out_file_name_size) { - int object_fd; - - int maps_fd; - NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY)); - FileDescriptor wrapped_maps_fd(maps_fd); - if (wrapped_maps_fd.get() < 0) { - return -1; - } - - int mem_fd; - NO_INTR(mem_fd = open("/proc/self/mem", O_RDONLY)); - FileDescriptor wrapped_mem_fd(mem_fd); - if (wrapped_mem_fd.get() < 0) { - return -1; - } - - // Iterate over maps and look for the map containing the pc. Then - // look into the symbol tables inside. - char buf[1024]; // Big enough for line of sane /proc/self/maps - int num_maps = 0; - LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf), 0); - while (true) { - num_maps++; - const char *cursor; - const char *eol; - if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line. - return -1; - } - - // Start parsing line in /proc/self/maps. Here is an example: - // - // 08048000-0804c000 r-xp 00000000 08:01 2142121 /bin/cat - // - // We want start address (08048000), end address (0804c000), flags - // (r-xp) and file name (/bin/cat). - - // Read start address. - cursor = GetHex(cursor, eol, &start_address); - if (cursor == eol || *cursor != '-') { - return -1; // Malformed line. - } - ++cursor; // Skip '-'. - - // Read end address. - uint64_t end_address; - cursor = GetHex(cursor, eol, &end_address); - if (cursor == eol || *cursor != ' ') { - return -1; // Malformed line. - } - ++cursor; // Skip ' '. - - // Read flags. Skip flags until we encounter a space or eol. - const char * const flags_start = cursor; - while (cursor < eol && *cursor != ' ') { - ++cursor; - } - // We expect at least four letters for flags (ex. "r-xp"). - if (cursor == eol || cursor < flags_start + 4) { - return -1; // Malformed line. - } - - // Determine the base address by reading ELF headers in process memory. - ElfW(Ehdr) ehdr; - // Skip non-readable maps. - if (flags_start[0] == 'r' && - ReadFromOffsetExact(mem_fd, &ehdr, sizeof(ElfW(Ehdr)), start_address) && - memcmp(ehdr.e_ident, ELFMAG, SELFMAG) == 0) { - switch (ehdr.e_type) { - case ET_EXEC: - base_address = 0; - break; - case ET_DYN: - // Find the segment containing file offset 0. This will correspond - // to the ELF header that we just read. Normally this will have - // virtual address 0, but this is not guaranteed. We must subtract - // the virtual address from the address where the ELF header was - // mapped to get the base address. - // - // If we fail to find a segment for file offset 0, use the address - // of the ELF header as the base address. - base_address = start_address; - for (unsigned i = 0; i != ehdr.e_phnum; ++i) { - ElfW(Phdr) phdr; - if (ReadFromOffsetExact( - mem_fd, &phdr, sizeof(phdr), - start_address + ehdr.e_phoff + i * sizeof(phdr)) && - phdr.p_type == PT_LOAD && phdr.p_offset == 0) { - base_address = start_address - phdr.p_vaddr; - break; - } - } - break; - default: - // ET_REL or ET_CORE. These aren't directly executable, so they don't - // affect the base address. - break; - } - } - - // Check start and end addresses. - if (!(start_address <= pc && pc < end_address)) { - continue; // We skip this map. PC isn't in this map. - } - - // Check flags. We are only interested in "r*x" maps. - if (flags_start[0] != 'r' || flags_start[2] != 'x') { - continue; // We skip this map. - } - ++cursor; // Skip ' '. - - // Read file offset. - uint64_t file_offset; - cursor = GetHex(cursor, eol, &file_offset); - if (cursor == eol || *cursor != ' ') { - return -1; // Malformed line. - } - ++cursor; // Skip ' '. - - // Skip to file name. "cursor" now points to dev. We need to - // skip at least two spaces for dev and inode. - int num_spaces = 0; - while (cursor < eol) { - if (*cursor == ' ') { - ++num_spaces; - } else if (num_spaces >= 2) { - // The first non-space character after skipping two spaces - // is the beginning of the file name. - break; - } - ++cursor; - } - if (cursor == eol) { - return -1; // Malformed line. - } - - // Finally, "cursor" now points to file name of our interest. - NO_INTR(object_fd = open(cursor, O_RDONLY)); - if (object_fd < 0) { - // Failed to open object file. Copy the object file name to - // |out_file_name|. - strncpy(out_file_name, cursor, out_file_name_size); - // Making sure |out_file_name| is always null-terminated. - out_file_name[out_file_name_size - 1] = '\0'; - return -1; - } - return object_fd; - } -} - -// POSIX doesn't define any async-signal safe function for converting -// an integer to ASCII. We'll have to define our own version. -// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the -// conversion was successful or NULL otherwise. It never writes more than "sz" -// bytes. Output will be truncated as needed, and a NUL character is always -// appended. -// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. -static char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) { - // Make sure we can write at least one NUL byte. - size_t n = 1; - if (n > sz) - return NULL; - - if (base < 2 || base > 16) { - buf[0] = '\000'; - return NULL; - } - - char *start = buf; - - uintptr_t j = i; - - // Handle negative numbers (only for base 10). - if (i < 0 && base == 10) { - // This does "j = -i" while avoiding integer overflow. - j = static_cast<uintptr_t>(-(i + 1)) + 1; - - // Make sure we can write the '-' character. - if (++n > sz) { - buf[0] = '\000'; - return NULL; - } - *start++ = '-'; - } - - // Loop until we have converted the entire number. Output at least one - // character (i.e. '0'). - char *ptr = start; - do { - // Make sure there is still enough space left in our output buffer. - if (++n > sz) { - buf[0] = '\000'; - return NULL; - } - - // Output the next digit. - *ptr++ = "0123456789abcdef"[j % base]; - j /= base; - - if (padding > 0) - padding--; - } while (j > 0 || padding > 0); - - // Terminate the output with a NUL character. - *ptr = '\000'; - - // Conversion to ASCII actually resulted in the digits being in reverse - // order. We can't easily generate them in forward order, as we can't tell - // the number of characters needed until we are done converting. - // So, now, we reverse the string (except for the possible "-" sign). - while (--ptr > start) { - char ch = *ptr; - *ptr = *start; - *start++ = ch; - } - return buf; -} - -// Safely appends string |source| to string |dest|. Never writes past the -// buffer size |dest_size| and guarantees that |dest| is null-terminated. -static void SafeAppendString(const char* source, char* dest, int dest_size) { - int dest_string_length = strlen(dest); - SAFE_ASSERT(dest_string_length < dest_size); - dest += dest_string_length; - dest_size -= dest_string_length; - strncpy(dest, source, dest_size); - // Making sure |dest| is always null-terminated. - dest[dest_size - 1] = '\0'; -} - -// Converts a 64-bit value into a hex string, and safely appends it to |dest|. -// Never writes past the buffer size |dest_size| and guarantees that |dest| is -// null-terminated. -static void SafeAppendHexNumber(uint64_t value, char* dest, int dest_size) { - // 64-bit numbers in hex can have up to 16 digits. - char buf[17] = {'\0'}; - SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size); -} - -// The implementation of our symbolization routine. If it -// successfully finds the symbol containing "pc" and obtains the -// symbol name, returns true and write the symbol name to "out". -// Otherwise, returns false. If Callback function is installed via -// InstallSymbolizeCallback(), the function is also called in this function, -// and "out" is used as its output. -// To keep stack consumption low, we would like this function to not -// get inlined. -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { - uint64_t pc0 = reinterpret_cast<uintptr_t>(pc); - uint64_t start_address = 0; - uint64_t base_address = 0; - int object_fd = -1; - - if (out_size < 1) { - return false; - } - out[0] = '\0'; - SafeAppendString("(", out, out_size); - - if (g_symbolize_open_object_file_callback) { - object_fd = g_symbolize_open_object_file_callback(pc0, start_address, - base_address, out + 1, - out_size - 1); - } else { - object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address, - base_address, - out + 1, - out_size - 1); - } - - FileDescriptor wrapped_object_fd(object_fd); - -#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES) - { -#else - // Check whether a file name was returned. - if (object_fd < 0) { -#endif - if (out[1]) { - // The object file containing PC was determined successfully however the - // object file was not opened successfully. This is still considered - // success because the object file name and offset are known and tools - // like asan_symbolize.py can be used for the symbolization. - out[out_size - 1] = '\0'; // Making sure |out| is always null-terminated. - SafeAppendString("+0x", out, out_size); - SafeAppendHexNumber(pc0 - base_address, out, out_size); - SafeAppendString(")", out, out_size); - return true; - } - // Failed to determine the object file containing PC. Bail out. - return false; - } - int elf_type = FileGetElfType(wrapped_object_fd.get()); - if (elf_type == -1) { - return false; - } - if (g_symbolize_callback) { - // Run the call back if it's installed. - // Note: relocation (and much of the rest of this code) will be - // wrong for prelinked shared libraries and PIE executables. - uint64_t relocation = (elf_type == ET_DYN) ? start_address : 0; - int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(), - pc, out, out_size, - relocation); - if (num_bytes_written > 0) { - out += num_bytes_written; - out_size -= num_bytes_written; - } - } - if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0, - out, out_size, base_address)) { - if (out[1] && !g_symbolize_callback) { - // The object file containing PC was opened successfully however the - // symbol was not found. The object may have been stripped. This is still - // considered success because the object file name and offset are known - // and tools like asan_symbolize.py can be used for the symbolization. - out[out_size - 1] = '\0'; // Making sure |out| is always null-terminated. - SafeAppendString("+0x", out, out_size); - SafeAppendHexNumber(pc0 - base_address, out, out_size); - SafeAppendString(")", out, out_size); - return true; - } - return false; - } - - // Symbolization succeeded. Now we try to demangle the symbol. - DemangleInplace(out, out_size); - return true; -} - -_END_GOOGLE_NAMESPACE_ - -#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) - -#include <dlfcn.h> -#include <string.h> - -_START_GOOGLE_NAMESPACE_ - -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { - Dl_info info; - if (dladdr(pc, &info)) { - if ((int)strlen(info.dli_sname) < out_size) { - strcpy(out, info.dli_sname); - // Symbolization succeeded. Now we try to demangle the symbol. - DemangleInplace(out, out_size); - return true; - } - } - return false; -} - -_END_GOOGLE_NAMESPACE_ - -#elif defined(OS_WINDOWS) || defined(OS_CYGWIN) - -#include <windows.h> -#include <dbghelp.h> - -#ifdef _MSC_VER -#pragma comment(lib, "dbghelp") -#endif - -_START_GOOGLE_NAMESPACE_ - -class SymInitializer { -public: - HANDLE process; - bool ready; - SymInitializer() : process(NULL), ready(false) { - // Initialize the symbol handler. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx - process = GetCurrentProcess(); - // Defer symbol loading. - // We do not request undecorated symbols with SYMOPT_UNDNAME - // because the mangling library calls UnDecorateSymbolName. - SymSetOptions(SYMOPT_DEFERRED_LOADS); - if (SymInitialize(process, NULL, true)) { - ready = true; - } - } - ~SymInitializer() { - SymCleanup(process); - // We do not need to close `HANDLE process` because it's a "pseudo handle." - } -private: - SymInitializer(const SymInitializer&); - SymInitializer& operator=(const SymInitializer&); -}; - -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { - const static SymInitializer symInitializer; - if (!symInitializer.ready) { - return false; - } - // Resolve symbol information from address. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx - char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; - SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(buf); - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_SYM_NAME; - // We use the ANSI version to ensure the string type is always `char *`. - // This could break if a symbol has Unicode in it. - BOOL ret = SymFromAddr(symInitializer.process, - reinterpret_cast<DWORD64>(pc), 0, symbol); - if (ret == 1 && static_cast<int>(symbol->NameLen) < out_size) { - // `NameLen` does not include the null terminating character. - strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1); - out[static_cast<size_t>(symbol->NameLen)] = '\0'; - // Symbolization succeeded. Now we try to demangle the symbol. - DemangleInplace(out, out_size); - return true; - } - return false; -} - -_END_GOOGLE_NAMESPACE_ - -#else -# error BUG: HAVE_SYMBOLIZE was wrongly set -#endif - -_START_GOOGLE_NAMESPACE_ - -bool Symbolize(void *pc, char *out, int out_size) { - SAFE_ASSERT(out_size >= 0); - return SymbolizeAndDemangle(pc, out, out_size); -} - -_END_GOOGLE_NAMESPACE_ - -#else /* HAVE_SYMBOLIZE */ - -#include <assert.h> - -#include "config.h" - -_START_GOOGLE_NAMESPACE_ - -// TODO: Support other environments. -bool Symbolize(void *pc, char *out, int out_size) { - assert(0); - return false; -} - -_END_GOOGLE_NAMESPACE_ - -#endif diff --git a/third_party/glog/src/symbolize.h b/third_party/glog/src/symbolize.h deleted file mode 100644 index c6f9ec4360ed..000000000000 --- a/third_party/glog/src/symbolize.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// This library provides Symbolize() function that symbolizes program -// counters to their corresponding symbol names on linux platforms. -// This library has a minimal implementation of an ELF symbol table -// reader (i.e. it doesn't depend on libelf, etc.). -// -// The algorithm used in Symbolize() is as follows. -// -// 1. Go through a list of maps in /proc/self/maps and find the map -// containing the program counter. -// -// 2. Open the mapped file and find a regular symbol table inside. -// Iterate over symbols in the symbol table and look for the symbol -// containing the program counter. If such a symbol is found, -// obtain the symbol name, and demangle the symbol if possible. -// If the symbol isn't found in the regular symbol table (binary is -// stripped), try the same thing with a dynamic symbol table. -// -// Note that Symbolize() is originally implemented to be used in -// FailureSignalHandler() in base/google.cc. Hence it doesn't use -// malloc() and other unsafe operations. It should be both -// thread-safe and async-signal-safe. - -#ifndef BASE_SYMBOLIZE_H_ -#define BASE_SYMBOLIZE_H_ - -#include "utilities.h" -#include "config.h" -#include "glog/logging.h" - -#ifdef HAVE_SYMBOLIZE - -#if defined(__ELF__) // defined by gcc -#if defined(__OpenBSD__) -#include <sys/exec_elf.h> -#else -#include <elf.h> -#endif - -#if !defined(ANDROID) -#include <link.h> // For ElfW() macro. -#endif - -// For systems where SIZEOF_VOID_P is not defined, determine it -// based on __LP64__ (defined by gcc on 64-bit systems) -#if !defined(SIZEOF_VOID_P) -# if defined(__LP64__) -# define SIZEOF_VOID_P 8 -# else -# define SIZEOF_VOID_P 4 -# endif -#endif - -// If there is no ElfW macro, let's define it by ourself. -#ifndef ElfW -# if SIZEOF_VOID_P == 4 -# define ElfW(type) Elf32_##type -# elif SIZEOF_VOID_P == 8 -# define ElfW(type) Elf64_##type -# else -# error "Unknown sizeof(void *)" -# endif -#endif - -_START_GOOGLE_NAMESPACE_ - -// Gets the section header for the given name, if it exists. Returns true on -// success. Otherwise, returns false. -bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, - ElfW(Shdr) *out); - -_END_GOOGLE_NAMESPACE_ - -#endif /* __ELF__ */ - -_START_GOOGLE_NAMESPACE_ - -// Restrictions on the callbacks that follow: -// - The callbacks must not use heaps but only use stacks. -// - The callbacks must be async-signal-safe. - -// Installs a callback function, which will be called right before a symbol name -// is printed. The callback is intended to be used for showing a file name and a -// line number preceding a symbol name. -// "fd" is a file descriptor of the object file containing the program -// counter "pc". The callback function should write output to "out" -// and return the size of the output written. On error, the callback -// function should return -1. -typedef int (*SymbolizeCallback)(int fd, - void* pc, - char* out, - size_t out_size, - uint64_t relocation); -void InstallSymbolizeCallback(SymbolizeCallback callback); - -// Installs a callback function, which will be called instead of -// OpenObjectFileContainingPcAndGetStartAddress. The callback is expected -// to searches for the object file (from /proc/self/maps) that contains -// the specified pc. If found, sets |start_address| to the start address -// of where this object file is mapped in memory, sets the module base -// address into |base_address|, copies the object file name into -// |out_file_name|, and attempts to open the object file. If the object -// file is opened successfully, returns the file descriptor. Otherwise, -// returns -1. |out_file_name_size| is the size of the file name buffer -// (including the null-terminator). -typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc, - uint64_t& start_address, - uint64_t& base_address, - char* out_file_name, - int out_file_name_size); -void InstallSymbolizeOpenObjectFileCallback( - SymbolizeOpenObjectFileCallback callback); - -_END_GOOGLE_NAMESPACE_ - -#endif - -_START_GOOGLE_NAMESPACE_ - -// Symbolizes a program counter. On success, returns true and write the -// symbol name to "out". The symbol name is demangled if possible -// (supports symbols generated by GCC 3.x or newer). Otherwise, -// returns false. -GOOGLE_GLOG_DLL_DECL bool Symbolize(void *pc, char *out, int out_size); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_SYMBOLIZE_H_ diff --git a/third_party/glog/src/symbolize_unittest.cc b/third_party/glog/src/symbolize_unittest.cc deleted file mode 100644 index 35cc2d31ff9b..000000000000 --- a/third_party/glog/src/symbolize_unittest.cc +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Satoru Takabayashi -// -// Unit tests for functions in symbolize.cc. - -#include "utilities.h" - -#include <signal.h> -#include <iostream> - -#include "glog/logging.h" -#include "symbolize.h" -#include "googletest.h" -#include "config.h" - -#ifdef HAVE_LIB_GFLAGS -#include <gflags/gflags.h> -using namespace GFLAGS_NAMESPACE; -#endif - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -#if defined(HAVE_STACKTRACE) - -#define always_inline - -// A wrapper function for Symbolize() to make the unit test simple. -static const char *TrySymbolize(void *pc) { - static char symbol[4096]; - if (Symbolize(pc, symbol, sizeof(symbol))) { - return symbol; - } else { - return NULL; - } -} - -# 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 __i386__ // always_inline isn't supported for x86_64 with GCC 4.1.0. -# undef always_inline -# define always_inline __attribute__((always_inline)) -# define HAVE_ALWAYS_INLINE -# endif // __i386__ -# else -# endif // __GNUC__ >= 4 -# if defined(__i386__) || defined(__x86_64__) -# define TEST_X86_32_AND_64 1 -# endif // defined(__i386__) || defined(__x86_64__) -#endif - -// Make them C linkage to avoid mangled names. -extern "C" { -void nonstatic_func(); -void nonstatic_func() { - volatile int a = 0; - ++a; -} - -static void static_func() { - volatile int a = 0; - ++a; -} -} - -TEST(Symbolize, Symbolize) { - // We do C-style cast since GCC 2.95.3 doesn't allow - // reinterpret_cast<void *>(&func). - - // Compilers should give us pointers to them. - EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); - - // The name of an internal linkage symbol is not specified; allow either a - // mangled or an unmangled name here. - const char *static_func_symbol = TrySymbolize((void *)(&static_func)); - CHECK(NULL != static_func_symbol); - EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 || - strcmp("static_func()", static_func_symbol) == 0); - - EXPECT_TRUE(NULL == TrySymbolize(NULL)); -} - -struct Foo { - static void func(int x); -}; - -void ATTRIBUTE_NOINLINE Foo::func(int x) { - volatile int a = x; - ++a; -} - -// With a modern GCC, Symbolize() should return demangled symbol -// names. Function parameters should be omitted. -#ifdef TEST_WITH_MODERN_GCC -TEST(Symbolize, SymbolizeWithDemangling) { - Foo::func(100); - EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func))); -} -#endif - -// Tests that verify that Symbolize footprint is within some limit. - -// To measure the stack footprint of the Symbolize function, we create -// a signal handler (for SIGUSR1 say) that calls the Symbolize function -// on an alternate stack. This alternate stack is initialized to some -// known pattern (0x55, 0x55, 0x55, ...). We then self-send this signal, -// and after the signal handler returns, look at the alternate stack -// buffer to see what portion has been touched. -// -// This trick gives us the the stack footprint of the signal handler. -// But the signal handler, even before the call to Symbolize, consumes -// some stack already. We however only want the stack usage of the -// Symbolize function. To measure this accurately, we install two signal -// handlers: one that does nothing and just returns, and another that -// calls Symbolize. The difference between the stack consumption of these -// two signals handlers should give us the Symbolize stack foorprint. - -static void *g_pc_to_symbolize; -static char g_symbolize_buffer[4096]; -static char *g_symbolize_result; - -static void EmptySignalHandler(int signo) {} - -static void SymbolizeSignalHandler(int signo) { - if (Symbolize(g_pc_to_symbolize, g_symbolize_buffer, - sizeof(g_symbolize_buffer))) { - g_symbolize_result = g_symbolize_buffer; - } else { - g_symbolize_result = NULL; - } -} - -const int kAlternateStackSize = 8096; -const char kAlternateStackFillValue = 0x55; - -// These helper functions look at the alternate stack buffer, and figure -// out what portion of this buffer has been touched - this is the stack -// consumption of the signal handler running on this alternate stack. -static ATTRIBUTE_NOINLINE bool StackGrowsDown(int *x) { - int y; - return &y < x; -} -static int GetStackConsumption(const char* alt_stack) { - int x; - if (StackGrowsDown(&x)) { - for (int i = 0; i < kAlternateStackSize; i++) { - if (alt_stack[i] != kAlternateStackFillValue) { - return (kAlternateStackSize - i); - } - } - } else { - for (int i = (kAlternateStackSize - 1); i >= 0; i--) { - if (alt_stack[i] != kAlternateStackFillValue) { - return i; - } - } - } - return -1; -} - -#ifdef HAVE_SIGALTSTACK - -// Call Symbolize and figure out the stack footprint of this call. -static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) { - - g_pc_to_symbolize = pc; - - // The alt-signal-stack cannot be heap allocated because there is a - // bug in glibc-2.2 where some signal handler setup code looks at the - // current stack pointer to figure out what thread is currently running. - // Therefore, the alternate stack must be allocated from the main stack - // itself. - char altstack[kAlternateStackSize]; - memset(altstack, kAlternateStackFillValue, kAlternateStackSize); - - // Set up the alt-signal-stack (and save the older one). - stack_t sigstk; - memset(&sigstk, 0, sizeof(stack_t)); - stack_t old_sigstk; - sigstk.ss_sp = altstack; - sigstk.ss_size = kAlternateStackSize; - sigstk.ss_flags = 0; - CHECK_ERR(sigaltstack(&sigstk, &old_sigstk)); - - // Set up SIGUSR1 and SIGUSR2 signal handlers (and save the older ones). - struct sigaction sa; - memset(&sa, 0, sizeof(struct sigaction)); - struct sigaction old_sa1, old_sa2; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK; - - // SIGUSR1 maps to EmptySignalHandler. - sa.sa_handler = EmptySignalHandler; - CHECK_ERR(sigaction(SIGUSR1, &sa, &old_sa1)); - - // SIGUSR2 maps to SymbolizeSignalHanlder. - sa.sa_handler = SymbolizeSignalHandler; - CHECK_ERR(sigaction(SIGUSR2, &sa, &old_sa2)); - - // Send SIGUSR1 signal and measure the stack consumption of the empty - // signal handler. - CHECK_ERR(kill(getpid(), SIGUSR1)); - int stack_consumption1 = GetStackConsumption(altstack); - - // Send SIGUSR2 signal and measure the stack consumption of the symbolize - // signal handler. - CHECK_ERR(kill(getpid(), SIGUSR2)); - int stack_consumption2 = GetStackConsumption(altstack); - - // The difference between the two stack consumption values is the - // stack footprint of the Symbolize function. - if (stack_consumption1 != -1 && stack_consumption2 != -1) { - *stack_consumed = stack_consumption2 - stack_consumption1; - } else { - *stack_consumed = -1; - } - - // Log the stack consumption values. - LOG(INFO) << "Stack consumption of empty signal handler: " - << stack_consumption1; - LOG(INFO) << "Stack consumption of symbolize signal handler: " - << stack_consumption2; - LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed; - - // Now restore the old alt-signal-stack and signal handlers. - CHECK_ERR(sigaltstack(&old_sigstk, NULL)); - CHECK_ERR(sigaction(SIGUSR1, &old_sa1, NULL)); - CHECK_ERR(sigaction(SIGUSR2, &old_sa2, NULL)); - - return g_symbolize_result; -} - -#ifdef __ppc64__ -// Symbolize stack consumption should be within 4kB. -const int kStackConsumptionUpperLimit = 4096; -#else -// Symbolize stack consumption should be within 2kB. -const int kStackConsumptionUpperLimit = 2048; -#endif - -TEST(Symbolize, SymbolizeStackConsumption) { - int stack_consumed; - const char* symbol; - - symbol = SymbolizeStackConsumption((void *)(&nonstatic_func), - &stack_consumed); - EXPECT_STREQ("nonstatic_func", symbol); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); - - // The name of an internal linkage symbol is not specified; allow either a - // mangled or an unmangled name here. - symbol = SymbolizeStackConsumption((void *)(&static_func), - &stack_consumed); - CHECK(NULL != symbol); - EXPECT_TRUE(strcmp("static_func", symbol) == 0 || - strcmp("static_func()", symbol) == 0); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); -} - -#ifdef TEST_WITH_MODERN_GCC -TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) { - Foo::func(100); - int stack_consumed; - const char* symbol; - - symbol = SymbolizeStackConsumption((void *)(&Foo::func), &stack_consumed); - - EXPECT_STREQ("Foo::func()", symbol); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); -} -#endif - -#endif // HAVE_SIGALTSTACK - -// x86 specific tests. Uses some inline assembler. -extern "C" { -inline void* always_inline inline_func() { - void *pc = NULL; -#ifdef TEST_X86_32_AND_64 - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); -#endif - return pc; -} - -void* ATTRIBUTE_NOINLINE non_inline_func(); -void* ATTRIBUTE_NOINLINE non_inline_func() { - void *pc = NULL; -#ifdef TEST_X86_32_AND_64 - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); -#endif - return pc; -} - -static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() { -#if defined(TEST_X86_32_AND_64) && defined(HAVE_ATTRIBUTE_NOINLINE) - void *pc = non_inline_func(); - const char *symbol = TrySymbolize(pc); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "non_inline_func"); - cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl; -#endif -} - -static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() { -#if defined(TEST_X86_32_AND_64) && defined(HAVE_ALWAYS_INLINE) - void *pc = inline_func(); // Must be inlined. - const char *symbol = TrySymbolize(pc); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, __FUNCTION__); - cout << "Test case TestWithPCInsideInlineFunction passed." << endl; -#endif -} -} - -// Test with a return address. -static void ATTRIBUTE_NOINLINE TestWithReturnAddress() { -#if defined(HAVE_ATTRIBUTE_NOINLINE) - void *return_address = __builtin_return_address(0); - const char *symbol = TrySymbolize(return_address); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "main"); - cout << "Test case TestWithReturnAddress passed." << endl; -#endif -} - -# elif defined(OS_WINDOWS) || defined(OS_CYGWIN) - -#ifdef _MSC_VER -#include <intrin.h> -#pragma intrinsic(_ReturnAddress) -#endif - -struct Foo { - static void func(int x); -}; - -__declspec(noinline) void Foo::func(int x) { - volatile int a = x; - ++a; -} - -TEST(Symbolize, SymbolizeWithDemangling) { - Foo::func(100); - const char* ret = TrySymbolize((void *)(&Foo::func)); - EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret); -} - -__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); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "main"); - cout << "Test case TestWithReturnAddress passed." << endl; -} -# endif // __ELF__ -#endif // HAVE_STACKTRACE - -int main(int argc, char **argv) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - InitGoogleTest(&argc, argv); -#if defined(HAVE_SYMBOLIZE) && defined(HAVE_STACKTRACE) -# if defined(__ELF__) - // We don't want to get affected by the callback interface, that may be - // used to install some callback function at InitGoogle() time. - InstallSymbolizeCallback(NULL); - - TestWithPCInsideInlineFunction(); - TestWithPCInsideNonInlineFunction(); - TestWithReturnAddress(); - return RUN_ALL_TESTS(); -# elif defined(OS_WINDOWS) || defined(OS_CYGWIN) - TestWithReturnAddress(); - return RUN_ALL_TESTS(); -# else // OS_WINDOWS - printf("PASS (no symbolize_unittest support)\n"); - return 0; -# endif // __ELF__ -#else - printf("PASS (no symbolize support)\n"); - return 0; -#endif // HAVE_SYMBOLIZE -} diff --git a/third_party/glog/src/utilities.cc b/third_party/glog/src/utilities.cc deleted file mode 100644 index 9a1e35d0229d..000000000000 --- a/third_party/glog/src/utilities.cc +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Shinichiro Hamaji - -#include "utilities.h" - -#include <stdio.h> -#include <stdlib.h> - -#include <signal.h> -#ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -#endif -#include <time.h> -#if defined(HAVE_SYSCALL_H) -#include <syscall.h> // for syscall() -#elif defined(HAVE_SYS_SYSCALL_H) -#include <sys/syscall.h> // for syscall() -#endif -#ifdef HAVE_SYSLOG_H -# include <syslog.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> // For geteuid. -#endif -#ifdef HAVE_PWD_H -# include <pwd.h> -#endif - -#include "base/googleinit.h" - -using std::string; - -_START_GOOGLE_NAMESPACE_ - -static const char* g_program_invocation_short_name = NULL; - -_END_GOOGLE_NAMESPACE_ - -// The following APIs are all internal. -#ifdef HAVE_STACKTRACE - -#include "stacktrace.h" -#include "symbolize.h" -#include "base/commandlineflags.h" - -GLOG_DEFINE_bool(symbolize_stacktrace, true, - "Symbolize the stack trace in the tombstone"); - -_START_GOOGLE_NAMESPACE_ - -typedef void DebugWriter(const char*, void*); - -// The %p field width for printf() functions is two characters per byte. -// For some environments, add two extra bytes for the leading "0x". -static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*); - -static void DebugWriteToStderr(const char* data, void *) { - // This one is signal-safe. - if (write(STDERR_FILENO, data, strlen(data)) < 0) { - // Ignore errors. - } -} - -static void DebugWriteToString(const char* data, void *arg) { - reinterpret_cast<string*>(arg)->append(data); -} - -#ifdef HAVE_SYMBOLIZE -// Print a program counter and its symbol name. -static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc, - const char * const prefix) { - char tmp[1024]; - const char *symbol = "(unknown)"; - // Symbolizes the previous address of pc because pc may be in the - // next function. The overrun happens when the function ends with - // a call to a function annotated noreturn (e.g. CHECK). - if (Symbolize(reinterpret_cast<char *>(pc) - 1, tmp, sizeof(tmp))) { - symbol = tmp; - } - char buf[1024]; - snprintf(buf, sizeof(buf), "%s@ %*p %s\n", - prefix, kPrintfPointerFieldWidth, pc, symbol); - writerfn(buf, arg); -} -#endif - -static void DumpPC(DebugWriter *writerfn, void *arg, void *pc, - const char * const prefix) { - char buf[100]; - snprintf(buf, sizeof(buf), "%s@ %*p\n", - prefix, kPrintfPointerFieldWidth, pc); - writerfn(buf, arg); -} - -// Dump current stack trace as directed by writerfn -static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { - // Print stack trace - void* stack[32]; - int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1); - for (int i = 0; i < depth; i++) { -#if defined(HAVE_SYMBOLIZE) - if (FLAGS_symbolize_stacktrace) { - DumpPCAndSymbol(writerfn, arg, stack[i], " "); - } else { - DumpPC(writerfn, arg, stack[i], " "); - } -#else - DumpPC(writerfn, arg, stack[i], " "); -#endif - } -} - -static void DumpStackTraceAndExit() { - DumpStackTrace(1, DebugWriteToStderr, NULL); - - // TODO(hamaji): Use signal instead of sigaction? - if (IsFailureSignalHandlerInstalled()) { - // Set the default signal handler for SIGABRT, to avoid invoking our - // own signal handler installed by InstallFailureSignalHandler(). -#ifdef HAVE_SIGACTION - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_handler = SIG_DFL; - sigaction(SIGABRT, &sig_action, NULL); -#elif defined(OS_WINDOWS) - signal(SIGABRT, SIG_DFL); -#endif // HAVE_SIGACTION - } - - abort(); -} - -_END_GOOGLE_NAMESPACE_ - -#endif // HAVE_STACKTRACE - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -const char* ProgramInvocationShortName() { - if (g_program_invocation_short_name != NULL) { - return g_program_invocation_short_name; - } else { - // TODO(hamaji): Use /proc/self/cmdline and so? - return "UNKNOWN"; - } -} - -bool IsGoogleLoggingInitialized() { - return g_program_invocation_short_name != NULL; -} - -#ifdef OS_WINDOWS -struct timeval { - long tv_sec, tv_usec; -}; - -// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd -// See COPYING for copyright information. -static int gettimeofday(struct timeval *tv, void* tz) { -#define EPOCHFILETIME (116444736000000000ULL) - FILETIME ft; - LARGE_INTEGER li; - uint64 tt; - - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - tt = (li.QuadPart - EPOCHFILETIME) / 10; - tv->tv_sec = tt / 1000000; - tv->tv_usec = tt % 1000000; - - return 0; -} -#endif - -int64 CycleClock_Now() { - // TODO(hamaji): temporary impementation - it might be too slow. - struct timeval tv; - gettimeofday(&tv, NULL); - return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec; -} - -int64 UsecToCycles(int64 usec) { - return usec; -} - -WallTime WallTime_Now() { - // Now, cycle clock is retuning microseconds since the epoch. - return CycleClock_Now() * 0.000001; -} - -static int32 g_main_thread_pid = getpid(); -int32 GetMainThreadPid() { - return g_main_thread_pid; -} - -bool PidHasChanged() { - int32 pid = getpid(); - if (g_main_thread_pid == pid) { - return false; - } - g_main_thread_pid = pid; - return true; -} - -pid_t GetTID() { - // On Linux and MacOSX, we try to use gettid(). -#if defined OS_LINUX || defined OS_MACOSX -#ifndef __NR_gettid -#ifdef 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) { - pid_t tid = syscall(__NR_gettid); - if (tid != -1) { - return tid; - } - // Technically, this variable has to be volatile, but there is a small - // performance penalty in accessing volatile variables and there should - // not be any serious adverse effect if a thread does not immediately see - // the value change to "true". - lacks_gettid = true; - } -#endif // OS_LINUX || OS_MACOSX - - // If gettid() could not be used, we use one of the following. -#if defined OS_LINUX - return getpid(); // Linux: getpid returns thread ID when gettid is absent -#elif defined OS_WINDOWS && !defined OS_CYGWIN - return GetCurrentThreadId(); -#elif defined(HAVE_PTHREAD) - // If none of the techniques above worked, we use pthread_self(). - return (pid_t)(uintptr_t)pthread_self(); -#else - return -1; -#endif -} - -const char* const_basename(const char* filepath) { - const char* base = strrchr(filepath, '/'); -#ifdef OS_WINDOWS // Look for either path separator in Windows - if (!base) - base = strrchr(filepath, '\\'); -#endif - return base ? (base+1) : filepath; -} - -static string g_my_user_name; -const string& MyUserName() { - return g_my_user_name; -} -static void MyUserNameInitializer() { - // TODO(hamaji): Probably this is not portable. -#if defined(OS_WINDOWS) - const char* user = getenv("USERNAME"); -#else - const char* user = getenv("USER"); -#endif - if (user != NULL) { - g_my_user_name = user; - } else { -#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H) - struct passwd pwd; - struct passwd* result = NULL; - char buffer[1024] = {'\0'}; - uid_t uid = geteuid(); - int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result); - if (pwuid_res == 0 && result) { - g_my_user_name = pwd.pw_name; - } else { - snprintf(buffer, sizeof(buffer), "uid%d", uid); - g_my_user_name = buffer; - } -#endif - if (g_my_user_name.empty()) { - g_my_user_name = "invalid-user"; - } - } - -} -REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()); - -#ifdef HAVE_STACKTRACE -void DumpStackTraceToString(string* stacktrace) { - DumpStackTrace(1, DebugWriteToString, stacktrace); -} -#endif - -// We use an atomic operation to prevent problems with calling CrashReason -// from inside the Mutex implementation (potentially through RAW_CHECK). -static const CrashReason* g_reason = 0; - -void SetCrashReason(const CrashReason* r) { - sync_val_compare_and_swap(&g_reason, - reinterpret_cast<const CrashReason*>(0), - r); -} - -void InitGoogleLoggingUtilities(const char* argv0) { - CHECK(!IsGoogleLoggingInitialized()) - << "You called InitGoogleLogging() twice!"; - const char* slash = strrchr(argv0, '/'); -#ifdef OS_WINDOWS - if (!slash) slash = strrchr(argv0, '\\'); -#endif - g_program_invocation_short_name = slash ? slash + 1 : argv0; - -#ifdef HAVE_STACKTRACE - InstallFailureFunction(&DumpStackTraceAndExit); -#endif -} - -void ShutdownGoogleLoggingUtilities() { - CHECK(IsGoogleLoggingInitialized()) - << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!"; - g_program_invocation_short_name = NULL; -#ifdef HAVE_SYSLOG_H - closelog(); -#endif -} - -} // namespace glog_internal_namespace_ - -_END_GOOGLE_NAMESPACE_ - -// Make an implementation of stacktrace compiled. -#ifdef STACKTRACE_H -# include STACKTRACE_H -# if 0 -// For include scanners which can't handle macro expansions. -# include "stacktrace_libunwind-inl.h" -# include "stacktrace_x86-inl.h" -# include "stacktrace_x86_64-inl.h" -# include "stacktrace_powerpc-inl.h" -# include "stacktrace_generic-inl.h" -# endif -#endif diff --git a/third_party/glog/src/utilities.h b/third_party/glog/src/utilities.h deleted file mode 100644 index c66f91467d06..000000000000 --- a/third_party/glog/src/utilities.h +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Shinichiro Hamaji -// -// Define utilties for glog internal usage. - -#ifndef UTILITIES_H__ -#define UTILITIES_H__ - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# define OS_WINDOWS -#elif defined(__CYGWIN__) || defined(__CYGWIN32__) -# define OS_CYGWIN -#elif defined(linux) || defined(__linux) || defined(__linux__) -# ifndef OS_LINUX -# define OS_LINUX -# endif -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) -# define OS_MACOSX -#elif defined(__FreeBSD__) -# define OS_FREEBSD -#elif defined(__NetBSD__) -# define OS_NETBSD -#elif defined(__OpenBSD__) -# define OS_OPENBSD -#else -// TODO(hamaji): Add other platforms. -#endif - -// printf macros for size_t, in the style of inttypes.h -#ifdef _LP64 -#define __PRIS_PREFIX "z" -#else -#define __PRIS_PREFIX -#endif - -// Use these macros after a % in a printf format string -// to get correct 32/64 bit behavior, like this: -// size_t size = records.size(); -// printf("%"PRIuS"\n", size); - -#define PRIdS __PRIS_PREFIX "d" -#define PRIxS __PRIS_PREFIX "x" -#define PRIuS __PRIS_PREFIX "u" -#define PRIXS __PRIS_PREFIX "X" -#define PRIoS __PRIS_PREFIX "o" - -#include "base/mutex.h" // This must go first so we get _XOPEN_SOURCE - -#include <string> - -#if defined(OS_WINDOWS) -# include "port.h" -#endif - -#include "config.h" -#include "glog/logging.h" - -// There are three different ways we can try to get the stack trace: -// -// 1) The libunwind library. This is still in development, and as a -// separate library adds a new dependency, but doesn't need a frame -// pointer. It also doesn't call malloc. -// -// 2) Our hand-coded stack-unwinder. This depends on a certain stack -// layout, which is used by gcc (and those systems using a -// gcc-compatible ABI) on x86 systems, at least since gcc 2.95. -// It uses the frame pointer to do its work. -// -// 3) The gdb unwinder -- also the one used by the c++ exception code. -// It's obviously well-tested, but has a fatal flaw: it can call -// malloc() from the unwinder. This is a problem because we're -// trying to use the unwinder to instrument malloc(). -// -// 4) The Windows API CaptureStackTrace. -// -// Note: if you add a new implementation here, make sure it works -// correctly when GetStackTrace() is called with max_depth == 0. -// Some code may do that. - -#if defined(HAVE_LIB_UNWIND) -# define STACKTRACE_H "stacktrace_libunwind-inl.h" -#elif !defined(NO_FRAME_POINTER) -# if defined(__i386__) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_x86-inl.h" -# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H -# define STACKTRACE_H "stacktrace_x86_64-inl.h" -# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_powerpc-inl.h" -# elif defined(OS_WINDOWS) -# define STACKTRACE_H "stacktrace_windows-inl.h" -# endif -#endif - -#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H) -# define STACKTRACE_H "stacktrace_generic-inl.h" -#endif - -#if defined(STACKTRACE_H) -# define HAVE_STACKTRACE -#endif - -#ifndef HAVE_SYMBOLIZE -// defined by gcc -#if defined(__ELF__) && defined(OS_LINUX) -# define HAVE_SYMBOLIZE -#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) -// Use dladdr to symbolize. -# define HAVE_SYMBOLIZE -#elif defined(OS_WINDOWS) -// Use DbgHelp to symbolize -# define HAVE_SYMBOLIZE -#endif -#endif // !defined(HAVE_SYMBOLIZE) - -#ifndef ARRAYSIZE -// There is a better way, but this is good enough for our purpose. -# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) -#endif - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NOINLINE __attribute__ ((noinline)) -# define HAVE_ATTRIBUTE_NOINLINE -#elif defined(OS_WINDOWS) -# define ATTRIBUTE_NOINLINE __declspec(noinline) -# define HAVE_ATTRIBUTE_NOINLINE -#else -# define ATTRIBUTE_NOINLINE -#endif - -const char* ProgramInvocationShortName(); - -bool IsGoogleLoggingInitialized(); - -int64 CycleClock_Now(); - -int64 UsecToCycles(int64 usec); - -typedef double WallTime; -WallTime WallTime_Now(); - -int32 GetMainThreadPid(); -bool PidHasChanged(); - -pid_t GetTID(); - -const std::string& MyUserName(); - -// Get the part of filepath after the last path separator. -// (Doesn't modify filepath, contrary to basename() in libgen.h.) -const char* const_basename(const char* filepath); - -// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't -// defined, we try the CPU specific logics (we only support x86 and -// x86_64 for now) first, then use a naive implementation, which has a -// race condition. -template<typename T> -inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) { -#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP) - return __sync_val_compare_and_swap(ptr, oldval, newval); -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - T ret; - __asm__ __volatile__("lock; cmpxchg %1, (%2);" - :"=a"(ret) - // GCC may produces %sil or %dil for - // constraint "r", but some of apple's gas - // dosn't know the 8 bit registers. - // We use "q" to avoid these registers. - :"q"(newval), "q"(ptr), "a"(oldval) - :"memory", "cc"); - return ret; -#else - T ret = *ptr; - if (ret == oldval) { - *ptr = newval; - } - return ret; -#endif -} - -void DumpStackTraceToString(std::string* stacktrace); - -struct CrashReason { - CrashReason() : filename(0), line_number(0), message(0), depth(0) {} - - const char* filename; - int line_number; - const char* message; - - // We'll also store a bit of stack trace context at the time of crash as - // it may not be available later on. - void* stack[32]; - int depth; -}; - -void SetCrashReason(const CrashReason* r); - -void InitGoogleLoggingUtilities(const char* argv0); -void ShutdownGoogleLoggingUtilities(); - -} // namespace glog_internal_namespace_ - -_END_GOOGLE_NAMESPACE_ - -using namespace GOOGLE_NAMESPACE::glog_internal_namespace_; - -#endif // UTILITIES_H__ diff --git a/third_party/glog/src/utilities_unittest.cc b/third_party/glog/src/utilities_unittest.cc deleted file mode 100644 index 38e847dfbf75..000000000000 --- a/third_party/glog/src/utilities_unittest.cc +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Shinichiro Hamaji -#include "utilities.h" -#include "googletest.h" -#include "glog/logging.h" - -#ifdef HAVE_LIB_GFLAGS -#include <gflags/gflags.h> -using namespace GFLAGS_NAMESPACE; -#endif - -using namespace GOOGLE_NAMESPACE; - -TEST(utilities, sync_val_compare_and_swap) { - bool now_entering = false; - EXPECT_FALSE(sync_val_compare_and_swap(&now_entering, false, true)); - EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true)); - EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true)); -} - -TEST(utilities, InitGoogleLoggingDeathTest) { - ASSERT_DEATH(InitGoogleLogging("foobar"), ""); -} - -int main(int argc, char **argv) { - InitGoogleLogging(argv[0]); - InitGoogleTest(&argc, argv); - - CHECK_EQ(RUN_ALL_TESTS(), 0); -} diff --git a/third_party/glog/src/vlog_is_on.cc b/third_party/glog/src/vlog_is_on.cc deleted file mode 100644 index e8fdbae7dcba..000000000000 --- a/third_party/glog/src/vlog_is_on.cc +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (c) 1999, 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Ray Sidney and many others -// -// Broken out from logging.cc by Soren Lassen -// logging_unittest.cc covers the functionality herein - -#include "utilities.h" - -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <cstdio> -#include <string> -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "base/googleinit.h" - -// glog doesn't have annotation -#define ANNOTATE_BENIGN_RACE(address, description) - -using std::string; - -GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this." -" Overridable by --vmodule."); - -GLOG_DEFINE_string(vmodule, "", "per-module verbose level." -" Argument is a comma-separated list of <module name>=<log level>." -" <module name> is a glob pattern, matched against the filename base" -" (that is, name ignoring .cc/.h./-inl.h)." -" <log level> overrides any value given by --v."); - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -// Used by logging_unittests.cc so can't make it static here. -GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, - size_t patt_len, - const char* str, - size_t str_len); - -// Implementation of fnmatch that does not need 0-termination -// of arguments and does not allocate any memory, -// but we only support "*" and "?" wildcards, not the "[...]" patterns. -// It's not a static function for the unittest. -GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, - size_t patt_len, - const char* str, - size_t str_len) { - size_t p = 0; - size_t s = 0; - while (1) { - if (p == patt_len && s == str_len) return true; - if (p == patt_len) return false; - if (s == str_len) return p+1 == patt_len && pattern[p] == '*'; - if (pattern[p] == str[s] || pattern[p] == '?') { - p += 1; - s += 1; - continue; - } - if (pattern[p] == '*') { - if (p+1 == patt_len) return true; - do { - if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) { - return true; - } - s += 1; - } while (s != str_len); - return false; - } - return false; - } -} - -} // namespace glog_internal_namespace_ - -using glog_internal_namespace_::SafeFNMatch_; - -int32 kLogSiteUninitialized = 1000; - -// List of per-module log levels from FLAGS_vmodule. -// Once created each element is never deleted/modified -// except for the vlog_level: other threads will read VModuleInfo blobs -// w/o locks and we'll store pointers to vlog_level at VLOG locations -// that will never go away. -// We can't use an STL struct here as we wouldn't know -// when it's safe to delete/update it: other threads need to use it w/o locks. -struct VModuleInfo { - string module_pattern; - mutable int32 vlog_level; // Conceptually this is an AtomicWord, but it's - // too much work to use AtomicWord type here - // w/o much actual benefit. - const VModuleInfo* next; -}; - -// This protects the following global variables. -static Mutex vmodule_lock; -// Pointer to head of the VModuleInfo list. -// It's a map from module pattern to logging level for those module(s). -static VModuleInfo* vmodule_list = 0; -// Boolean initialization flag. -static bool inited_vmodule = false; - -// L >= vmodule_lock. -static void VLOG2Initializer() { - vmodule_lock.AssertHeld(); - // Can now parse --vmodule flag and initialize mapping of module-specific - // logging levels. - inited_vmodule = false; - const char* vmodule = FLAGS_vmodule.c_str(); - const char* sep; - VModuleInfo* head = NULL; - VModuleInfo* tail = NULL; - while ((sep = strchr(vmodule, '=')) != NULL) { - string pattern(vmodule, sep - vmodule); - int module_level; - if (sscanf(sep, "=%d", &module_level) == 1) { - VModuleInfo* info = new VModuleInfo; - info->module_pattern = pattern; - info->vlog_level = module_level; - if (head) tail->next = info; - else head = info; - tail = info; - } - // Skip past this entry - vmodule = strchr(sep, ','); - if (vmodule == NULL) break; - vmodule++; // Skip past "," - } - if (head) { // Put them into the list at the head: - tail->next = vmodule_list; - vmodule_list = head; - } - inited_vmodule = true; -} - -// This can be called very early, so we use SpinLock and RAW_VLOG here. -int SetVLOGLevel(const char* module_pattern, int log_level) { - int result = FLAGS_v; - int const pattern_len = strlen(module_pattern); - bool found = false; - { - MutexLock l(&vmodule_lock); // protect whole read-modify-write - for (const VModuleInfo* info = vmodule_list; - info != NULL; info = info->next) { - if (info->module_pattern == module_pattern) { - if (!found) { - result = info->vlog_level; - found = true; - } - info->vlog_level = log_level; - } else if (!found && - SafeFNMatch_(info->module_pattern.c_str(), - info->module_pattern.size(), - module_pattern, pattern_len)) { - result = info->vlog_level; - found = true; - } - } - if (!found) { - VModuleInfo* info = new VModuleInfo; - info->module_pattern = module_pattern; - info->vlog_level = log_level; - info->next = vmodule_list; - vmodule_list = info; - } - } - RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level); - return result; -} - -// NOTE: Individual VLOG statements cache the integer log level pointers. -// NOTE: This function must not allocate memory or require any locks. -bool InitVLOG3__(int32** site_flag, int32* site_default, - const char* fname, int32 verbose_level) { - MutexLock l(&vmodule_lock); - bool read_vmodule_flag = inited_vmodule; - if (!read_vmodule_flag) { - VLOG2Initializer(); - } - - // protect the errno global in case someone writes: - // VLOG(..) << "The last error was " << strerror(errno) - int old_errno = errno; - - // site_default normally points to FLAGS_v - int32* site_flag_value = site_default; - - // Get basename for file - const char* base = strrchr(fname, '/'); - base = base ? (base+1) : fname; - const char* base_end = strchr(base, '.'); - size_t base_length = base_end ? size_t(base_end - base) : strlen(base); - - // Trim out trailing "-inl" if any - if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) { - base_length -= 4; - } - - // TODO: Trim out _unittest suffix? Perhaps it is better to have - // the extra control and just leave it there. - - // find target in vector of modules, replace site_flag_value with - // a module-specific verbose level, if any. - for (const VModuleInfo* info = vmodule_list; - info != NULL; info = info->next) { - if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(), - base, base_length)) { - site_flag_value = &info->vlog_level; - // value at info->vlog_level is now what controls - // the VLOG at the caller site forever - break; - } - } - - // Cache the vlog value pointer if --vmodule flag has been parsed. - ANNOTATE_BENIGN_RACE(site_flag, - "*site_flag may be written by several threads," - " but the value will be the same"); - if (read_vmodule_flag) *site_flag = site_flag_value; - - // restore the errno in case something recoverable went wrong during - // the initialization of the VLOG mechanism (see above note "protect the..") - errno = old_errno; - return *site_flag_value >= verbose_level; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/windows/config.h b/third_party/glog/src/windows/config.h deleted file mode 100755 index 2d23fb08159d..000000000000 --- a/third_party/glog/src/windows/config.h +++ /dev/null @@ -1,21 +0,0 @@ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* Namespace for Google classes */ -#define GOOGLE_NAMESPACE google - -/* Stops putting the code inside the Google namespace */ -#define _END_GOOGLE_NAMESPACE_ } - -/* Puts following code inside the Google namespace */ -#define _START_GOOGLE_NAMESPACE_ namespace google { - -/* Always the empty-string on non-windows systems. On windows, should be - "__declspec(dllexport)". This way, when we compile the dll, we export our - functions/classes. It's safe to define this here because config.h is only - used internally, to compile the DLL, and every DLL source file #includes - "config.h" before anything else. */ -#ifndef GOOGLE_GLOG_DLL_DECL -# define GOOGLE_GLOG_IS_A_DLL 1 /* not set if you're statically linking */ -# define GOOGLE_GLOG_DLL_DECL __declspec(dllexport) -# define GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) -#endif diff --git a/third_party/glog/src/windows/dirent.h b/third_party/glog/src/windows/dirent.h deleted file mode 100644 index f7a46dafcbf1..000000000000 --- a/third_party/glog/src/windows/dirent.h +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * Dirent interface for Microsoft Visual Studio - * - * Copyright (C) 1998-2019 Toni Ronkko - * This file is part of dirent. Dirent may be freely distributed - * under the MIT license. For all details and documentation, see - * https://github.com/tronkko/dirent - */ -#ifndef DIRENT_H -#define DIRENT_H - -/* Hide warnings about unreferenced local functions */ -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wunused-function" -#elif defined(_MSC_VER) -# pragma warning(disable:4505) -#elif defined(__GNUC__) -# pragma GCC diagnostic ignored "-Wunused-function" -#endif - -/* - * Include windows.h without Windows Sockets 1.1 to prevent conflicts with - * Windows Sockets 2.0. - */ -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> - -#include <stdio.h> -#include <stdarg.h> -#include <wchar.h> -#include <string.h> -#include <stdlib.h> -#include <malloc.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> - -/* Indicates that d_type field is available in dirent structure */ -#define _DIRENT_HAVE_D_TYPE - -/* Indicates that d_namlen field is available in dirent structure */ -#define _DIRENT_HAVE_D_NAMLEN - -/* Entries missing from MSVC 6.0 */ -#if !defined(FILE_ATTRIBUTE_DEVICE) -# define FILE_ATTRIBUTE_DEVICE 0x40 -#endif - -/* File type and permission flags for stat(), general mask */ -#if !defined(S_IFMT) -# define S_IFMT _S_IFMT -#endif - -/* Directory bit */ -#if !defined(S_IFDIR) -# define S_IFDIR _S_IFDIR -#endif - -/* Character device bit */ -#if !defined(S_IFCHR) -# define S_IFCHR _S_IFCHR -#endif - -/* Pipe bit */ -#if !defined(S_IFFIFO) -# define S_IFFIFO _S_IFFIFO -#endif - -/* Regular file bit */ -#if !defined(S_IFREG) -# define S_IFREG _S_IFREG -#endif - -/* Read permission */ -#if !defined(S_IREAD) -# define S_IREAD _S_IREAD -#endif - -/* Write permission */ -#if !defined(S_IWRITE) -# define S_IWRITE _S_IWRITE -#endif - -/* Execute permission */ -#if !defined(S_IEXEC) -# define S_IEXEC _S_IEXEC -#endif - -/* Pipe */ -#if !defined(S_IFIFO) -# define S_IFIFO _S_IFIFO -#endif - -/* Block device */ -#if !defined(S_IFBLK) -# define S_IFBLK 0 -#endif - -/* Link */ -#if !defined(S_IFLNK) -# define S_IFLNK 0 -#endif - -/* Socket */ -#if !defined(S_IFSOCK) -# define S_IFSOCK 0 -#endif - -/* Read user permission */ -#if !defined(S_IRUSR) -# define S_IRUSR S_IREAD -#endif - -/* Write user permission */ -#if !defined(S_IWUSR) -# define S_IWUSR S_IWRITE -#endif - -/* Execute user permission */ -#if !defined(S_IXUSR) -# define S_IXUSR 0 -#endif - -/* Read group permission */ -#if !defined(S_IRGRP) -# define S_IRGRP 0 -#endif - -/* Write group permission */ -#if !defined(S_IWGRP) -# define S_IWGRP 0 -#endif - -/* Execute group permission */ -#if !defined(S_IXGRP) -# define S_IXGRP 0 -#endif - -/* Read others permission */ -#if !defined(S_IROTH) -# define S_IROTH 0 -#endif - -/* Write others permission */ -#if !defined(S_IWOTH) -# define S_IWOTH 0 -#endif - -/* Execute others permission */ -#if !defined(S_IXOTH) -# define S_IXOTH 0 -#endif - -/* Maximum length of file name */ -#if !defined(PATH_MAX) -# define PATH_MAX MAX_PATH -#endif -#if !defined(FILENAME_MAX) -# define FILENAME_MAX MAX_PATH -#endif -#if !defined(NAME_MAX) -# define NAME_MAX FILENAME_MAX -#endif - -/* File type flags for d_type */ -#define DT_UNKNOWN 0 -#define DT_REG S_IFREG -#define DT_DIR S_IFDIR -#define DT_FIFO S_IFIFO -#define DT_SOCK S_IFSOCK -#define DT_CHR S_IFCHR -#define DT_BLK S_IFBLK -#define DT_LNK S_IFLNK - -/* Macros for converting between st_mode and d_type */ -#define IFTODT(mode) ((mode) & S_IFMT) -#define DTTOIF(type) (type) - -/* - * File type macros. Note that block devices, sockets and links cannot be - * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are - * only defined for compatibility. These macros should always return false - * on Windows. - */ -#if !defined(S_ISFIFO) -# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) -#endif -#if !defined(S_ISDIR) -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) -# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISLNK) -# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -#endif -#if !defined(S_ISSOCK) -# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -#endif -#if !defined(S_ISCHR) -# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISBLK) -# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) -#endif - -/* Return the exact length of the file name without zero terminator */ -#define _D_EXACT_NAMLEN(p) ((p)->d_namlen) - -/* Return the maximum size of a file name */ -#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1) - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Wide-character version */ -struct _wdirent { - /* Always zero */ - long d_ino; - - /* File position within stream */ - long d_off; - - /* Structure size */ - unsigned short d_reclen; - - /* Length of name without \0 */ - size_t d_namlen; - - /* File type */ - int d_type; - - /* File name */ - wchar_t d_name[PATH_MAX+1]; -}; -typedef struct _wdirent _wdirent; - -struct _WDIR { - /* Current directory entry */ - struct _wdirent ent; - - /* Private file data */ - WIN32_FIND_DATAW data; - - /* True if data is valid */ - int cached; - - /* Win32 search handle */ - HANDLE handle; - - /* Initial directory name */ - wchar_t *patt; -}; -typedef struct _WDIR _WDIR; - -/* Multi-byte character version */ -struct dirent { - /* Always zero */ - long d_ino; - - /* File position within stream */ - long d_off; - - /* Structure size */ - unsigned short d_reclen; - - /* Length of name without \0 */ - size_t d_namlen; - - /* File type */ - int d_type; - - /* File name */ - char d_name[PATH_MAX+1]; -}; -typedef struct dirent dirent; - -struct DIR { - struct dirent ent; - struct _WDIR *wdirp; -}; -typedef struct DIR DIR; - - -/* Dirent functions */ -static DIR *opendir (const char *dirname); -static _WDIR *_wopendir (const wchar_t *dirname); - -static struct dirent *readdir (DIR *dirp); -static struct _wdirent *_wreaddir (_WDIR *dirp); - -static int readdir_r( - DIR *dirp, struct dirent *entry, struct dirent **result); -static int _wreaddir_r( - _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result); - -static int closedir (DIR *dirp); -static int _wclosedir (_WDIR *dirp); - -static void rewinddir (DIR* dirp); -static void _wrewinddir (_WDIR* dirp); - -static int scandir (const char *dirname, struct dirent ***namelist, - int (*filter)(const struct dirent*), - int (*compare)(const struct dirent**, const struct dirent**)); - -static int alphasort (const struct dirent **a, const struct dirent **b); - -static int versionsort (const struct dirent **a, const struct dirent **b); - - -/* For compatibility with Symbian */ -#define wdirent _wdirent -#define WDIR _WDIR -#define wopendir _wopendir -#define wreaddir _wreaddir -#define wclosedir _wclosedir -#define wrewinddir _wrewinddir - - -/* Internal utility functions */ -static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); -static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); - -static int dirent_mbstowcs_s( - size_t *pReturnValue, - wchar_t *wcstr, - size_t sizeInWords, - const char *mbstr, - size_t count); - -static int dirent_wcstombs_s( - size_t *pReturnValue, - char *mbstr, - size_t sizeInBytes, - const wchar_t *wcstr, - size_t count); - -static void dirent_set_errno (int error); - - -/* - * Open directory stream DIRNAME for read and return a pointer to the - * internal working area that is used to retrieve individual directory - * entries. - */ -static _WDIR* -_wopendir( - const wchar_t *dirname) -{ - _WDIR *dirp; - DWORD n; - wchar_t *p; - - /* Must have directory name */ - if (dirname == NULL || dirname[0] == '\0') { - dirent_set_errno (ENOENT); - return NULL; - } - - /* Allocate new _WDIR structure */ - dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); - if (!dirp) { - return NULL; - } - - /* Reset _WDIR structure */ - dirp->handle = INVALID_HANDLE_VALUE; - dirp->patt = NULL; - dirp->cached = 0; - - /* - * Compute the length of full path plus zero terminator - * - * Note that on WinRT there's no way to convert relative paths - * into absolute paths, so just assume it is an absolute path. - */ -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Desktop */ - n = GetFullPathNameW (dirname, 0, NULL, NULL); -#else - /* WinRT */ - n = wcslen (dirname); -#endif - - /* Allocate room for absolute directory name and search pattern */ - dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); - if (dirp->patt == NULL) { - goto exit_closedir; - } - - /* - * Convert relative directory name to an absolute one. This - * allows rewinddir() to function correctly even when current - * working directory is changed between opendir() and rewinddir(). - * - * Note that on WinRT there's no way to convert relative paths - * into absolute paths, so just assume it is an absolute path. - */ -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Desktop */ - n = GetFullPathNameW (dirname, n, dirp->patt, NULL); - if (n <= 0) { - goto exit_closedir; - } -#else - /* WinRT */ - wcsncpy_s (dirp->patt, n+1, dirname, n); -#endif - - /* Append search pattern \* to the directory name */ - p = dirp->patt + n; - switch (p[-1]) { - case '\\': - case '/': - case ':': - /* Directory ends in path separator, e.g. c:\temp\ */ - /*NOP*/; - break; - - default: - /* Directory name doesn't end in path separator */ - *p++ = '\\'; - } - *p++ = '*'; - *p = '\0'; - - /* Open directory stream and retrieve the first entry */ - if (!dirent_first (dirp)) { - goto exit_closedir; - } - - /* Success */ - return dirp; - - /* Failure */ -exit_closedir: - _wclosedir (dirp); - return NULL; -} - -/* - * Read next directory entry. - * - * Returns pointer to static directory entry which may be overwritten by - * subsequent calls to _wreaddir(). - */ -static struct _wdirent* -_wreaddir( - _WDIR *dirp) -{ - struct _wdirent *entry; - - /* - * Read directory entry to buffer. We can safely ignore the return value - * as entry will be set to NULL in case of error. - */ - (void) _wreaddir_r (dirp, &dirp->ent, &entry); - - /* Return pointer to statically allocated directory entry */ - return entry; -} - -/* - * Read next directory entry. - * - * Returns zero on success. If end of directory stream is reached, then sets - * result to NULL and returns zero. - */ -static int -_wreaddir_r( - _WDIR *dirp, - struct _wdirent *entry, - struct _wdirent **result) -{ - WIN32_FIND_DATAW *datap; - - /* Read next directory entry */ - datap = dirent_next (dirp); - if (datap) { - size_t n; - DWORD attr; - - /* - * Copy file name as wide-character string. If the file name is too - * long to fit in to the destination buffer, then truncate file name - * to PATH_MAX characters and zero-terminate the buffer. - */ - n = 0; - while (n < PATH_MAX && datap->cFileName[n] != 0) { - entry->d_name[n] = datap->cFileName[n]; - n++; - } - entry->d_name[n] = 0; - - /* Length of file name excluding zero terminator */ - entry->d_namlen = n; - - /* File type */ - attr = datap->dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entry->d_type = DT_CHR; - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entry->d_type = DT_DIR; - } else { - entry->d_type = DT_REG; - } - - /* Reset dummy fields */ - entry->d_ino = 0; - entry->d_off = 0; - entry->d_reclen = sizeof (struct _wdirent); - - /* Set result address */ - *result = entry; - - } else { - - /* Return NULL to indicate end of directory */ - *result = NULL; - - } - - return /*OK*/0; -} - -/* - * Close directory stream opened by opendir() function. This invalidates the - * DIR structure as well as any directory entry read previously by - * _wreaddir(). - */ -static int -_wclosedir( - _WDIR *dirp) -{ - int ok; - if (dirp) { - - /* Release search handle */ - if (dirp->handle != INVALID_HANDLE_VALUE) { - FindClose (dirp->handle); - } - - /* Release search pattern */ - free (dirp->patt); - - /* Release directory structure */ - free (dirp); - ok = /*success*/0; - - } else { - - /* Invalid directory stream */ - dirent_set_errno (EBADF); - ok = /*failure*/-1; - - } - return ok; -} - -/* - * Rewind directory stream such that _wreaddir() returns the very first - * file name again. - */ -static void -_wrewinddir( - _WDIR* dirp) -{ - if (dirp) { - /* Release existing search handle */ - if (dirp->handle != INVALID_HANDLE_VALUE) { - FindClose (dirp->handle); - } - - /* Open new search handle */ - dirent_first (dirp); - } -} - -/* Get first directory entry (internal) */ -static WIN32_FIND_DATAW* -dirent_first( - _WDIR *dirp) -{ - WIN32_FIND_DATAW *datap; - DWORD error; - - /* Open directory and retrieve the first entry */ - dirp->handle = FindFirstFileExW( - dirp->patt, FindExInfoStandard, &dirp->data, - FindExSearchNameMatch, NULL, 0); - if (dirp->handle != INVALID_HANDLE_VALUE) { - - /* a directory entry is now waiting in memory */ - datap = &dirp->data; - dirp->cached = 1; - - } else { - - /* Failed to open directory: no directory entry in memory */ - dirp->cached = 0; - datap = NULL; - - /* Set error code */ - error = GetLastError (); - switch (error) { - case ERROR_ACCESS_DENIED: - /* No read access to directory */ - dirent_set_errno (EACCES); - break; - - case ERROR_DIRECTORY: - /* Directory name is invalid */ - dirent_set_errno (ENOTDIR); - break; - - case ERROR_PATH_NOT_FOUND: - default: - /* Cannot find the file */ - dirent_set_errno (ENOENT); - } - - } - return datap; -} - -/* - * Get next directory entry (internal). - * - * Returns - */ -static WIN32_FIND_DATAW* -dirent_next( - _WDIR *dirp) -{ - WIN32_FIND_DATAW *p; - - /* Get next directory entry */ - if (dirp->cached != 0) { - - /* A valid directory entry already in memory */ - p = &dirp->data; - dirp->cached = 0; - - } else if (dirp->handle != INVALID_HANDLE_VALUE) { - - /* Get the next directory entry from stream */ - if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { - /* Got a file */ - p = &dirp->data; - } else { - /* The very last entry has been processed or an error occurred */ - FindClose (dirp->handle); - dirp->handle = INVALID_HANDLE_VALUE; - p = NULL; - } - - } else { - - /* End of directory stream reached */ - p = NULL; - - } - - return p; -} - -/* - * Open directory stream using plain old C-string. - */ -static DIR* -opendir( - const char *dirname) -{ - struct DIR *dirp; - - /* Must have directory name */ - if (dirname == NULL || dirname[0] == '\0') { - dirent_set_errno (ENOENT); - return NULL; - } - - /* Allocate memory for DIR structure */ - dirp = (DIR*) malloc (sizeof (struct DIR)); - if (!dirp) { - return NULL; - } - { - int error; - wchar_t wname[PATH_MAX + 1]; - size_t n; - - /* Convert directory name to wide-character string */ - error = dirent_mbstowcs_s( - &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); - if (error) { - /* - * Cannot convert file name to wide-character string. This - * occurs if the string contains invalid multi-byte sequences or - * the output buffer is too small to contain the resulting - * string. - */ - goto exit_free; - } - - - /* Open directory stream using wide-character name */ - dirp->wdirp = _wopendir (wname); - if (!dirp->wdirp) { - goto exit_free; - } - - } - - /* Success */ - return dirp; - - /* Failure */ -exit_free: - free (dirp); - return NULL; -} - -/* - * Read next directory entry. - */ -static struct dirent* -readdir( - DIR *dirp) -{ - struct dirent *entry; - - /* - * Read directory entry to buffer. We can safely ignore the return value - * as entry will be set to NULL in case of error. - */ - (void) readdir_r (dirp, &dirp->ent, &entry); - - /* Return pointer to statically allocated directory entry */ - return entry; -} - -/* - * Read next directory entry into called-allocated buffer. - * - * Returns zero on success. If the end of directory stream is reached, then - * sets result to NULL and returns zero. - */ -static int -readdir_r( - DIR *dirp, - struct dirent *entry, - struct dirent **result) -{ - WIN32_FIND_DATAW *datap; - - /* Read next directory entry */ - datap = dirent_next (dirp->wdirp); - if (datap) { - size_t n; - int error; - - /* Attempt to convert file name to multi-byte string */ - error = dirent_wcstombs_s( - &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); - - /* - * If the file name cannot be represented by a multi-byte string, - * then attempt to use old 8+3 file name. This allows traditional - * Unix-code to access some file names despite of unicode - * characters, although file names may seem unfamiliar to the user. - * - * Be ware that the code below cannot come up with a short file - * name unless the file system provides one. At least - * VirtualBox shared folders fail to do this. - */ - if (error && datap->cAlternateFileName[0] != '\0') { - error = dirent_wcstombs_s( - &n, entry->d_name, PATH_MAX + 1, - datap->cAlternateFileName, PATH_MAX + 1); - } - - if (!error) { - DWORD attr; - - /* Length of file name excluding zero terminator */ - entry->d_namlen = n - 1; - - /* File attributes */ - attr = datap->dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entry->d_type = DT_CHR; - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entry->d_type = DT_DIR; - } else { - entry->d_type = DT_REG; - } - - /* Reset dummy fields */ - entry->d_ino = 0; - entry->d_off = 0; - entry->d_reclen = sizeof (struct dirent); - - } else { - - /* - * Cannot convert file name to multi-byte string so construct - * an erroneous directory entry and return that. Note that - * we cannot return NULL as that would stop the processing - * of directory entries completely. - */ - entry->d_name[0] = '?'; - entry->d_name[1] = '\0'; - entry->d_namlen = 1; - entry->d_type = DT_UNKNOWN; - entry->d_ino = 0; - entry->d_off = -1; - entry->d_reclen = 0; - - } - - /* Return pointer to directory entry */ - *result = entry; - - } else { - - /* No more directory entries */ - *result = NULL; - - } - - return /*OK*/0; -} - -/* - * Close directory stream. - */ -static int -closedir( - DIR *dirp) -{ - int ok; - if (dirp) { - - /* Close wide-character directory stream */ - ok = _wclosedir (dirp->wdirp); - dirp->wdirp = NULL; - - /* Release multi-byte character version */ - free (dirp); - - } else { - - /* Invalid directory stream */ - dirent_set_errno (EBADF); - ok = /*failure*/-1; - - } - return ok; -} - -/* - * Rewind directory stream to beginning. - */ -static void -rewinddir( - DIR* dirp) -{ - /* Rewind wide-character string directory stream */ - _wrewinddir (dirp->wdirp); -} - -/* - * Scan directory for entries. - */ -static int -scandir( - const char *dirname, - struct dirent ***namelist, - int (*filter)(const struct dirent*), - int (*compare)(const struct dirent**, const struct dirent**)) -{ - struct dirent **files = NULL; - size_t size = 0; - size_t allocated = 0; - const size_t init_size = 1; - DIR *dir = NULL; - struct dirent *entry; - struct dirent *tmp = NULL; - size_t i; - int result = 0; - - /* Open directory stream */ - dir = opendir (dirname); - if (dir) { - - /* Read directory entries to memory */ - while (1) { - - /* Enlarge pointer table to make room for another pointer */ - if (size >= allocated) { - void *p; - size_t num_entries; - - /* Compute number of entries in the enlarged pointer table */ - if (size < init_size) { - /* Allocate initial pointer table */ - num_entries = init_size; - } else { - /* Double the size */ - num_entries = size * 2; - } - - /* Allocate first pointer table or enlarge existing table */ - p = realloc (files, sizeof (void*) * num_entries); - if (p != NULL) { - /* Got the memory */ - files = (dirent**) p; - allocated = num_entries; - } else { - /* Out of memory */ - result = -1; - break; - } - - } - - /* Allocate room for temporary directory entry */ - if (tmp == NULL) { - tmp = (struct dirent*) malloc (sizeof (struct dirent)); - if (tmp == NULL) { - /* Cannot allocate temporary directory entry */ - result = -1; - break; - } - } - - /* Read directory entry to temporary area */ - if (readdir_r (dir, tmp, &entry) == /*OK*/0) { - - /* Did we get an entry? */ - if (entry != NULL) { - int pass; - - /* Determine whether to include the entry in result */ - if (filter) { - /* Let the filter function decide */ - pass = filter (tmp); - } else { - /* No filter function, include everything */ - pass = 1; - } - - if (pass) { - /* Store the temporary entry to pointer table */ - files[size++] = tmp; - tmp = NULL; - - /* Keep up with the number of files */ - result++; - } - - } else { - - /* - * End of directory stream reached => sort entries and - * exit. - */ - qsort (files, size, sizeof (void*), - (int (*) (const void*, const void*)) compare); - break; - - } - - } else { - /* Error reading directory entry */ - result = /*Error*/ -1; - break; - } - - } - - } else { - /* Cannot open directory */ - result = /*Error*/ -1; - } - - /* Release temporary directory entry */ - free (tmp); - - /* Release allocated memory on error */ - if (result < 0) { - for (i = 0; i < size; i++) { - free (files[i]); - } - free (files); - files = NULL; - } - - /* Close directory stream */ - if (dir) { - closedir (dir); - } - - /* Pass pointer table to caller */ - if (namelist) { - *namelist = files; - } - return result; -} - -/* Alphabetical sorting */ -static int -alphasort( - const struct dirent **a, const struct dirent **b) -{ - return strcoll ((*a)->d_name, (*b)->d_name); -} - -/* Sort versions */ -static int -versionsort( - const struct dirent **a, const struct dirent **b) -{ - /* FIXME: implement strverscmp and use that */ - return alphasort (a, b); -} - -/* Convert multi-byte string to wide character string */ -static int -dirent_mbstowcs_s( - size_t *pReturnValue, - wchar_t *wcstr, - size_t sizeInWords, - const char *mbstr, - size_t count) -{ - int error; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 or later */ - error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); - -#else - - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; - - /* Convert to wide-character string (or count characters) */ - n = mbstowcs (wcstr, mbstr, sizeInWords); - if (!wcstr || n < count) { - - /* Zero-terminate output buffer */ - if (wcstr && sizeInWords) { - if (n >= sizeInWords) { - n = sizeInWords - 1; - } - wcstr[n] = 0; - } - - /* Length of resulting multi-byte string WITH zero terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } - - /* Success */ - error = 0; - - } else { - - /* Could not convert string */ - error = 1; - - } - -#endif - return error; -} - -/* Convert wide-character string to multi-byte string */ -static int -dirent_wcstombs_s( - size_t *pReturnValue, - char *mbstr, - size_t sizeInBytes, /* max size of mbstr */ - const wchar_t *wcstr, - size_t count) -{ - int error; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 or later */ - error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); - -#else - - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; - - /* Convert to multi-byte string (or count the number of bytes needed) */ - n = wcstombs (mbstr, wcstr, sizeInBytes); - if (!mbstr || n < count) { - - /* Zero-terminate output buffer */ - if (mbstr && sizeInBytes) { - if (n >= sizeInBytes) { - n = sizeInBytes - 1; - } - mbstr[n] = '\0'; - } - - /* Length of resulting multi-bytes string WITH zero-terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } - - /* Success */ - error = 0; - - } else { - - /* Cannot convert string */ - error = 1; - - } - -#endif - return error; -} - -/* Set errno variable */ -static void -dirent_set_errno( - int error) -{ -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 and later */ - _set_errno (error); - -#else - - /* Non-Microsoft compiler or older Microsoft compiler */ - errno = error; - -#endif -} - - -#ifdef __cplusplus -} -#endif -#endif /*DIRENT_H*/ diff --git a/third_party/glog/src/windows/glog/log_severity.h b/third_party/glog/src/windows/glog/log_severity.h deleted file mode 100644 index 22a4191ab8bb..000000000000 --- a/third_party/glog/src/windows/glog/log_severity.h +++ /dev/null @@ -1,96 +0,0 @@ -// This file is automatically generated from src/glog/log_severity.h -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef BASE_LOG_SEVERITY_H__ -#define BASE_LOG_SEVERITY_H__ - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// Variables of type LogSeverity are widely taken to lie in the range -// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if -// you ever need to change their values or add a new severity. -typedef int LogSeverity; - -const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3, - NUM_SEVERITIES = 4; -#ifndef GLOG_NO_ABBREVIATED_SEVERITIES -# ifdef ERROR -# error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail. -# endif -const int INFO = GLOG_INFO, WARNING = GLOG_WARNING, - ERROR = GLOG_ERROR, FATAL = GLOG_FATAL; -#endif - -// DFATAL is FATAL in debug mode, ERROR in normal mode -#ifdef NDEBUG -#define DFATAL_LEVEL ERROR -#else -#define DFATAL_LEVEL FATAL -#endif - -extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; - -// NDEBUG usage helpers related to (RAW_)DCHECK: -// -// DEBUG_MODE is for small !NDEBUG uses like -// if (DEBUG_MODE) foo.CheckThatFoo(); -// instead of substantially more verbose -// #ifndef NDEBUG -// foo.CheckThatFoo(); -// #endif -// -// IF_DEBUG_MODE is for small !NDEBUG uses like -// IF_DEBUG_MODE( string error; ) -// DCHECK(Foo(&error)) << error; -// instead of substantially more verbose -// #ifndef NDEBUG -// string error; -// DCHECK(Foo(&error)) << error; -// #endif -// -#ifdef NDEBUG -enum { DEBUG_MODE = 0 }; -#define IF_DEBUG_MODE(x) -#else -enum { DEBUG_MODE = 1 }; -#define IF_DEBUG_MODE(x) x -#endif - -#endif // BASE_LOG_SEVERITY_H__ diff --git a/third_party/glog/src/windows/glog/logging.h b/third_party/glog/src/windows/glog/logging.h deleted file mode 100755 index e111bf07c46c..000000000000 --- a/third_party/glog/src/windows/glog/logging.h +++ /dev/null @@ -1,1690 +0,0 @@ -// This file is automatically generated from src/glog/logging.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 1999, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Ray Sidney -// -// This file contains #include information about logging-related stuff. -// Pretty much everybody needs to #include this file so that they can -// log various happenings. -// -#ifndef _LOGGING_H_ -#define _LOGGING_H_ - -#include <errno.h> -#include <string.h> -#include <time.h> -#include <iosfwd> -#include <ostream> -#include <sstream> -#include <string> -#if 0 -# include <unistd.h> -#endif -#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)) -#else -#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) -#define GLOG_MSVC_POP_WARNING() -#endif - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// We care a lot about number of bits things take up. Unfortunately, -// systems define their bit-specific ints in a lot of different ways. -// We use our own way, and have a typedef to get there. -// Note: these commands below may look like "#if 1" or "#if 0", but -// that's because they were constructed that way at ./configure time. -// Look at logging.h.in to see how they're calculated (based on your config). -#if 0 -#include <stdint.h> // the normal place uint16_t is defined -#endif -#if 0 -#include <sys/types.h> // the normal place u_int16_t is defined -#endif -#if 0 -#include <inttypes.h> // a third place for uint16_t or u_int16_t -#endif - -#if 0 -#include <gflags/gflags.h> -#endif - -namespace google { - -#if 0 // the C99 format -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#elif 0 // the BSD format -typedef int32_t int32; -typedef u_int32_t uint32; -typedef int64_t int64; -typedef u_int64_t uint64; -#elif 1 // the windows (vc7) format -typedef __int32 int32; -typedef unsigned __int32 uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; -#else -#error Do not know how to define a 32-bit integer quantity on your system -#endif - -} - -// The global value of GOOGLE_STRIP_LOG. All the messages logged to -// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. -// If it can be determined at compile time that the message will not be -// printed, the statement will be compiled out. -// -// Example: to strip out all INFO and WARNING messages, use the value -// of 2 below. To make an exception for WARNING messages from a single -// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including -// base/logging.h -#ifndef GOOGLE_STRIP_LOG -#define GOOGLE_STRIP_LOG 0 -#endif - -// GCC can be told that a certain branch is not likely to be taken (for -// instance, a CHECK failure), and use that information in static analysis. -// Giving it this information can help it optimize for the common case in -// the absence of better information (ie. -fprofile-arcs). -// -#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN -#if 0 -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x -#endif -#endif - -#ifndef GOOGLE_PREDICT_FALSE -#if 0 -#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_FALSE(x) x -#endif -#endif - -#ifndef GOOGLE_PREDICT_TRUE -#if 0 -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#define GOOGLE_PREDICT_TRUE(x) x -#endif -#endif - - -// Make a bunch of macros for logging. The way to log things is to stream -// things to LOG(<a particular severity level>). E.g., -// -// LOG(INFO) << "Found " << num_cookies << " cookies"; -// -// You can capture log messages in a string, rather than reporting them -// immediately: -// -// vector<string> errors; -// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; -// -// This pushes back the new error onto 'errors'; if given a NULL pointer, -// it reports the error via LOG(ERROR). -// -// You can also do conditional logging: -// -// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// You can also do occasional logging (log every n'th occurrence of an -// event): -// -// LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// The above will cause log messages to be output on the 1st, 11th, 21st, ... -// times it is executed. Note that the special google::COUNTER value is used -// to identify which repetition is happening. -// -// You can also do occasional conditional logging (log every n'th -// occurrence of an event, when condition is satisfied): -// -// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER -// << "th big cookie"; -// -// You can log messages the first N times your code executes a line. E.g. -// -// LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; -// -// Outputs log messages for the first 20 times it is executed. -// -// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. -// These log to syslog as well as to the normal logs. If you use these at -// all, you need to be aware that syslog can drastically reduce performance, -// especially if it is configured for remote logging! Don't use these -// unless you fully understand this and have a concrete need to use them. -// Even then, try to minimize your use of them. -// -// There are also "debug mode" logging macros like the ones above: -// -// DLOG(INFO) << "Found cookies"; -// -// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// All "debug mode" logging is compiled away to nothing for non-debug mode -// compiles. -// -// We also have -// -// LOG_ASSERT(assertion); -// DLOG_ASSERT(assertion); -// -// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; -// -// There are "verbose level" logging macros. They look like -// -// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; -// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; -// -// These always log at the INFO log level (when they log at all). -// The verbose logging can also be turned on module-by-module. For instance, -// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 -// will cause: -// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} -// b. VLOG(1) and lower messages to be printed from file.{h,cc} -// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" -// d. VLOG(0) and lower messages to be printed from elsewhere -// -// The wildcarding functionality shown by (c) supports both '*' (match -// 0 or more characters) and '?' (match any single character) wildcards. -// -// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as -// -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished with just VLOG(2) << ...; -// } -// -// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" -// condition macros for sample cases, when some extra computation and -// preparation for logs is not needed. -// VLOG_IF(1, (size > 1024)) -// << "I'm printed when size is more than 1024 and when you run the " -// "program with --v=1 or more"; -// VLOG_EVERY_N(1, 10) -// << "I'm printed every 10th occurrence, and when you run the program " -// "with --v=1 or more. Present occurence is " << google::COUNTER; -// VLOG_IF_EVERY_N(1, (size > 1024), 10) -// << "I'm printed on every 10th occurence of case when size is more " -// " than 1024, when you run the program with --v=1 or more. "; -// "Present occurence is " << google::COUNTER; -// -// The supported severity levels for macros that allow you to specify one -// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. -// Note that messages of a given severity are logged not only in the -// logfile for that severity, but also in all logfiles of lower severity. -// E.g., a message of severity FATAL will be logged to the logfiles of -// severity FATAL, ERROR, WARNING, and INFO. -// -// There is also the special severity of DFATAL, which logs FATAL in -// debug mode, ERROR in normal mode. -// -// Very important: logging a message at the FATAL severity level causes -// the program to terminate (after the message is logged). -// -// Unless otherwise specified, logs will be written to the filename -// "<program name>.<hostname>.<user name>.log.<severity level>.", followed -// by the date, time, and pid (you can't prevent the date, time, and pid -// from being in the filename). -// -// The logging code takes two flags: -// --v=# set the verbose level -// --logtostderr log all the messages to stderr instead of to logfiles - -// LOG LINE PREFIX FORMAT -// -// Log lines have this form: -// -// Lyyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg... -// -// where the fields are defined as follows: -// -// L A single character, representing the log level -// (eg 'I' for INFO) -// yyyy The year -// mm The month (zero padded; ie May is '05') -// dd The day (zero padded) -// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds -// threadid The space-padded thread ID as returned by GetTID() -// (this matches the PID on Linux) -// file The file name -// line The line number -// msg The user-supplied message -// -// Example: -// -// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog -// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 -// -// NOTE: although the microseconds are useful for comparing events on -// a single machine, clocks on different machines may not be well -// synchronized. Hence, use caution when comparing the low bits of -// timestamps from different machines. - -#ifndef DECLARE_VARIABLE -#define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(google::int32, I, name, int32) - -// 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 GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#endif - -// Set whether log messages go to stderr instead of logfiles -DECLARE_bool(logtostderr); - -// Set whether log messages go to stderr in addition to logfiles. -DECLARE_bool(alsologtostderr); - -// Set color messages logged to stderr (if supported by terminal). -DECLARE_bool(colorlogtostderr); - -// Log messages at a level >= this flag are automatically sent to -// stderr in addition to log files. -DECLARE_int32(stderrthreshold); - -// Set whether the log prefix should be prepended to each line of output. -DECLARE_bool(log_prefix); - -// Log messages at a level <= this flag are buffered. -// Log messages at a higher level are flushed immediately. -DECLARE_int32(logbuflevel); - -// Sets the maximum number of seconds which logs may be buffered for. -DECLARE_int32(logbufsecs); - -// Log suppression level: messages logged at a lower level than this -// are suppressed. -DECLARE_int32(minloglevel); - -// If specified, logfiles are written into this directory instead of the -// default logging directory. -DECLARE_string(log_dir); - -// Set the log file mode. -DECLARE_int32(logfile_mode); - -// Sets the path of the directory into which to put additional links -// to the log files. -DECLARE_string(log_link); - -DECLARE_int32(v); // in vlog_is_on.cc - -// Sets the maximum log file size (in MB). -DECLARE_int32(max_log_size); - -// Sets whether to avoid logging to the disk if the disk is full. -DECLARE_bool(stop_logging_if_full_disk); - -#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef DECLARE_VARIABLE -#undef DECLARE_bool -#undef DECLARE_int32 -#undef DECLARE_string -#endif - -// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for -// security reasons. See LOG(severtiy) below. - -// A few definitions of macros that don't generate much code. Since -// LOG(INFO) and its ilk are used all over our code, it's -// 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) -#else -#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) -#else -#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) -#else -#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) -#else -#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 -#else -#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 -#elif GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_FATAL) -#else -#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal() -#endif - -#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, &google::LogMessage::SendToLog) -#define SYSLOG_INFO(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_WARNING(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_WARNING(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_ERROR(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_ERROR(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_FATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_FATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_DFATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_DFATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ - &google::LogMessage::SendToSyslogAndLog) - -#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 = NULL; \ - LPSTR msg = reinterpret_cast<LPSTR>(&message); \ - DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ - FORMAT_MESSAGE_FROM_SYSTEM, \ - 0, result, 0, msg, 100, NULL); \ - 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., -// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny -// subtle difference between ostream member streaming functions (e.g., -// ostream::operator<<(int) and ostream non-member streaming functions -// (e.g., ::operator<<(ostream&, string&): it turns out that it's -// impossible to stream something like a string directly to an unnamed -// ostream. We employ a neat hack by calling the stream() member -// function of LogMessage which seems to avoid the problem. -#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() -#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() - -namespace google { - -// They need the definitions of integer types. -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Initialize google's logging library. You will see the program name -// specified by argv0 in log outputs. -GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); - -// Shutdown google's logging library. -GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); - -// Install a function which will be called after LOG(FATAL). -GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); - -// Enable/Disable old log cleaner. -GOOGLE_GLOG_DLL_DECL void EnableLogCleaner(int overdue_days); -GOOGLE_GLOG_DLL_DECL void DisableLogCleaner(); - - -class LogSink; // defined below - -// If a non-NULL sink pointer is given, we push this message to that sink. -// For LOG_TO_SINK we then do normal LOG(severity) logging as well. -// This is useful for capturing messages and passing/storing them -// somewhere more specific than the global log of the process. -// Argument types: -// LogSink* sink; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -#define LOG_TO_SINK(sink, severity) \ - google::LogMessage( \ - __FILE__, __LINE__, \ - google::GLOG_ ## severity, \ - static_cast<google::LogSink*>(sink), true).stream() -#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ - google::LogMessage( \ - __FILE__, __LINE__, \ - google::GLOG_ ## severity, \ - static_cast<google::LogSink*>(sink), false).stream() - -// If a non-NULL string pointer is given, we write this message to that string. -// We then do normal LOG(severity) logging as well. -// This is useful for capturing messages and storing them somewhere more -// specific than the global log of the process. -// Argument types: -// string* message; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -// NOTE: LOG(severity) expands to LogMessage().stream() for the specified -// severity. -#define LOG_TO_STRING(severity, message) \ - LOG_TO_STRING_##severity(static_cast<string*>(message)).stream() - -// If a non-NULL pointer is given, we push the message onto the end -// of a vector of strings; otherwise, we report it with LOG(severity). -// This is handy for capturing messages and perhaps passing them back -// to the caller, rather than reporting them immediately. -// Argument types: -// LogSeverity severity; -// vector<string> *outvec; -// The cast is to disambiguate NULL arguments. -#define LOG_STRING(severity, outvec) \ - LOG_TO_STRING_##severity(static_cast<std::vector<std::string>*>(outvec)).stream() - -#define LOG_IF(severity, condition) \ - static_cast<void>(0), \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) -#define SYSLOG_IF(severity, condition) \ - static_cast<void>(0), \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity) - -#define LOG_ASSERT(condition) \ - LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition -#define SYSLOG_ASSERT(condition) \ - SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition - -// CHECK dies with a fatal error if condition is not true. It is *not* -// controlled by DCHECK_IS_ON(), so the check will be executed regardless of -// compilation mode. Therefore, it is safe to do things like: -// CHECK(fp->Write(x) == 4) -#define CHECK(condition) \ - LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A container for a string pointer which can be evaluated to a bool - -// true iff the pointer is NULL. -struct CheckOpString { - CheckOpString(std::string* str) : str_(str) { } - // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), - // so there's no point in cleaning up str_. - operator bool() const { - return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); - } - std::string* str_; -}; - -// Function is overloaded for integral types to allow static const -// integrals declared in classes and not defined to be used as arguments to -// CHECK* macros. It's not encouraged though. -template <class T> -inline const T& GetReferenceableValue(const T& t) { return t; } -inline char GetReferenceableValue(char t) { return t; } -inline unsigned char GetReferenceableValue(unsigned char t) { return t; } -inline signed char GetReferenceableValue(signed char t) { return t; } -inline short GetReferenceableValue(short t) { return t; } -inline unsigned short GetReferenceableValue(unsigned short t) { return t; } -inline int GetReferenceableValue(int t) { return t; } -inline unsigned int GetReferenceableValue(unsigned int t) { return t; } -inline long GetReferenceableValue(long t) { return t; } -inline unsigned long GetReferenceableValue(unsigned long t) { return t; } -inline long long GetReferenceableValue(long long t) { return t; } -inline unsigned long long GetReferenceableValue(unsigned long long t) { - return t; -} - -// This is a dummy class to define the following operator. -struct DummyClassToDefineOperator {}; - -} - -// Define global operator<< to declare using ::operator<<. -// This declaration will allow use to use CHECK macros for user -// defined classes which have operator<< (e.g., stl_logging.h). -inline std::ostream& operator<<( - std::ostream& out, const google::DummyClassToDefineOperator&) { - return out; -} - -namespace google { - -// This formats a value for a failing CHECK_XX statement. Ordinarily, -// it uses the definition for operator<<, with a few special cases below. -template <typename T> -inline void MakeCheckOpValueString(std::ostream* os, const T& v) { - (*os) << v; -} - -// Overrides for char types provide readable values for unprintable -// characters. -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const signed char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); - -// Build the error message string. Specify no inlining for code size. -template <typename T1, typename T2> -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) - ; - -namespace base { -namespace internal { - -// If "s" is less than base_logging::INFO, returns base_logging::INFO. -// If "s" is greater than base_logging::FATAL, returns -// base_logging::ERROR. Otherwise, returns "s". -LogSeverity NormalizeSeverity(LogSeverity s); - -} // namespace internal - -// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX -// statement. See MakeCheckOpString for sample usage. Other -// approaches were considered: use of a template method (e.g., -// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1, -// base::Print<T2>, &v2), however this approach has complications -// related to volatile arguments and function-pointer arguments). -class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { - public: - // Inserts "exprtext" and " (" to the stream. - explicit CheckOpMessageBuilder(const char *exprtext); - // Deletes "stream_". - ~CheckOpMessageBuilder(); - // For inserting the first variable. - std::ostream* ForVar1() { return stream_; } - // For inserting the second variable (adds an intermediate " vs. "). - std::ostream* ForVar2(); - // Get the result (inserts the closing ")"). - std::string* NewString(); - - private: - std::ostringstream *stream_; -}; - -} // namespace base - -template <typename T1, typename T2> -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { - base::CheckOpMessageBuilder comb(exprtext); - MakeCheckOpValueString(comb.ForVar1(), v1); - MakeCheckOpValueString(comb.ForVar2(), v2); - return comb.NewString(); -} - -// Helper functions for CHECK_OP macro. -// The (int, int) specialization works around the issue that the compiler -// will not instantiate the template version of the function on values of -// unnamed enum type - see comment below. -#define DEFINE_CHECK_OP_IMPL(name, op) \ - template <typename T1, typename T2> \ - inline std::string* name##Impl(const T1& v1, const T2& v2, \ - const char* exprtext) { \ - if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ - else return MakeCheckOpString(v1, v2, exprtext); \ - } \ - inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ - return name##Impl<int, int>(v1, v2, exprtext); \ - } - -// We use the full name Check_EQ, Check_NE, etc. in case the file including -// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. -// This happens if, for example, those are used as token names in a -// yacc grammar. -DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? -DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. -DEFINE_CHECK_OP_IMPL(Check_LE, <=) -DEFINE_CHECK_OP_IMPL(Check_LT, < ) -DEFINE_CHECK_OP_IMPL(Check_GE, >=) -DEFINE_CHECK_OP_IMPL(Check_GT, > ) -#undef DEFINE_CHECK_OP_IMPL - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. - -#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)) -#elif DCHECK_IS_ON() -// In debug mode, avoid constructing CheckOpStrings if possible, -// to reduce the overhead of CHECK statments by 2x. -// Real DCHECK-heavy tests have seen 1.5x speedups. - -// The meaning of "string" might be different between now and -// when this macro gets invoked (e.g., if someone is experimenting -// with other string implementations that get defined after this -// 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() -#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() -#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) -#else -#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 -// including the two values when the result is not as expected. The values -// must have operator<<(ostream, ...) defined. -// -// You may append to the error message like so: -// CHECK_NE(1, 2) << ": The world must be ending!"; -// -// We are very careful to ensure that each argument is evaluated exactly -// once, and that anything which is legal to pass as a function argument is -// legal here. In particular, the arguments may be temporary expressions -// which will end up being destroyed at the end of the apparent statement, -// for example: -// CHECK_EQ(string("abc")[1], 'b'); -// -// WARNING: These don't compile correctly if one of the arguments is a pointer -// and the other is NULL. To work around this, simply static_cast NULL to the -// type of the desired pointer. - -#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) -#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) -#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) -#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) -#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) -#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) - -// Check that the input is non NULL. This very useful in constructor -// initializer lists. - -#define CHECK_NOTNULL(val) \ - google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) - -// Helper functions for string comparisons. -// To avoid bloat, the definitions are in logging.cc. -#define DECLARE_CHECK_STROP_IMPL(func, expected) \ - GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ - const char* s1, const char* s2, const char* names); -DECLARE_CHECK_STROP_IMPL(strcmp, true) -DECLARE_CHECK_STROP_IMPL(strcmp, false) -DECLARE_CHECK_STROP_IMPL(strcasecmp, true) -DECLARE_CHECK_STROP_IMPL(strcasecmp, false) -#undef DECLARE_CHECK_STROP_IMPL - -// Helper macro for string comparisons. -// Don't use this macro directly in your code, use CHECK_STREQ et al below. -#define CHECK_STROP(func, op, expected, s1, s2) \ - while (google::CheckOpString _result = \ - google::Check##func##expected##Impl((s1), (s2), \ - #s1 " " #op " " #s2)) \ - LOG(FATAL) << *_result.str_ - - -// String (char*) equality/inequality checks. -// CASE versions are case-insensitive. -// -// Note that "s1" and "s2" may be temporary strings which are destroyed -// by the compiler at the end of the current "full expression" -// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). - -#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) -#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) -#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) -#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) - -#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) -#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) - -#define CHECK_DOUBLE_EQ(val1, val2) \ - do { \ - CHECK_LE((val1), (val2)+0.000000000000001L); \ - CHECK_GE((val1), (val2)-0.000000000000001L); \ - } while (0) - -#define CHECK_NEAR(val1, val2, margin) \ - do { \ - CHECK_LE((val1), (val2)+(margin)); \ - CHECK_GE((val1), (val2)-(margin)); \ - } while (0) - -// perror()..googly style! -// -// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and -// CHECK equivalents with the addition that they postpend a description -// of the current state of errno to their output lines. - -#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() - -#define GOOGLE_PLOG(severity, counter) \ - google::ErrnoLogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, counter, \ - &google::LogMessage::SendToLog) - -#define PLOG_IF(severity, condition) \ - static_cast<void>(0), \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity) - -// A CHECK() macro that postpends errno if the condition is false. E.g. -// -// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } -#define PCHECK(condition) \ - PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A CHECK() macro that lets you assert the success of a function that -// returns -1 and sets errno in case of an error. E.g. -// -// CHECK_ERR(mkdir(path, 0700)); -// -// or -// -// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; -#define CHECK_ERR(invocation) \ -PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ - << #invocation - -// Use macro expansion to create, for each use of LOG_EVERY_N(), static -// variables with the __LINE__ expansion as part of the variable name. -#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) -#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line - -#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) -#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) - -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (condition && \ - ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - google::ErrnoLogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0; \ - if (LOG_OCCURRENCES <= n) \ - ++LOG_OCCURRENCES; \ - if (LOG_OCCURRENCES <= n) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -namespace glog_internal_namespace_ { -template <bool> -struct CompileAssert { -}; -struct CrashReason; - -// Returns true if FailureSignalHandler is installed. -// Needs to be exported since it's used by the signalhandler_unittest. -GOOGLE_GLOG_DLL_DECL bool IsFailureSignalHandlerInstalled(); -} // namespace glog_internal_namespace_ - -#define LOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) - -#define SYSLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog) - -#define PLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) - -#define LOG_FIRST_N(severity, n) \ - SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog) - -#define LOG_IF_EVERY_N(severity, condition, n) \ - SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog) - -// We want the special COUNTER value available for LOG_EVERY_X()'ed messages -enum PRIVATE_Counter {COUNTER}; - -#ifdef GLOG_NO_ABBREVIATED_SEVERITIES -// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets -// 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 -// Needed for LOG_IS_ON(ERROR). -const LogSeverity GLOG_0 = GLOG_ERROR; -#else -// Users may include windows.h after logging.h without -// 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 -#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_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) - -#else // !DCHECK_IS_ON() - -#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 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_IF_EVERY_N(severity, condition, n) \ - static_cast<void>(0), \ - (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#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_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_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_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) - -// 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_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_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) - -#endif // DCHECK_IS_ON() - -// Log only in verbose mode. - -#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) - -#define VLOG_IF(verboselevel, condition) \ - LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) - -#define VLOG_EVERY_N(verboselevel, n) \ - LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) - -#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ - LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) - -namespace base_logging { - -// LogMessage::LogStream is a std::ostream backed by this streambuf. -// This class ignores overflow and leaves two bytes at the end of the -// buffer to allow for a '\n' and '\0'. -class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf { - public: - // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\0'. - LogStreamBuf(char *buf, int len) { - setp(buf, buf + len - 2); - } - - // This effectively ignores overflow. - virtual int_type overflow(int_type ch) { - return ch; - } - - // Legacy public ostrstream method. - size_t pcount() const { return pptr() - pbase(); } - char* pbase() const { return std::streambuf::pbase(); } -}; - -} // namespace base_logging - -// -// This class more or less represents a particular log message. You -// create an instance of LogMessage and then stream stuff to it. -// When you finish streaming to it, ~LogMessage is called and the -// full message gets streamed to the appropriate destination. -// -// You shouldn't actually use LogMessage's constructor to log things, -// though. You should use the LOG() macro (and variants thereof) -// above. -class GOOGLE_GLOG_DLL_DECL LogMessage { -public: - enum { - // Passing kNoLogPrefix for the line number disables the - // log-message prefix. Useful for using the LogMessage - // infrastructure as a printing utility. See also the --log_prefix - // flag for controlling the log-message prefix on an - // application-wide basis. - kNoLogPrefix = -1 - }; - - // LogStream inherit from non-DLL-exported class (std::ostrstream) - // and VC++ produces a warning for this situation. - // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ - // 2005 if you are deriving from a type in the Standard C++ Library" - // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx - // Let's just ignore the warning. -GLOG_MSVC_PUSH_DISABLE_WARNING(4275) - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { -GLOG_MSVC_POP_WARNING() - public: - LogStream(char *buf, int len, int ctr) - : std::ostream(NULL), - streambuf_(buf, len), - ctr_(ctr), - self_(this) { - rdbuf(&streambuf_); - } - - int ctr() const { return ctr_; } - void set_ctr(int ctr) { ctr_ = ctr; } - LogStream* self() const { return self_; } - - // Legacy std::streambuf methods. - size_t pcount() const { return streambuf_.pcount(); } - char* pbase() const { return streambuf_.pbase(); } - char* str() const { return pbase(); } - - private: - LogStream(const LogStream&); - LogStream& operator=(const LogStream&); - base_logging::LogStreamBuf streambuf_; - int ctr_; // Counter hack (for the LOG_EVERY_X() macro) - LogStream *self_; // Consistency check hack - }; - -public: - // icc 8 requires this typedef to avoid an internal compiler error. - typedef void (LogMessage::*SendMethod)(); - - LogMessage(const char* file, int line, LogSeverity severity, int ctr, - SendMethod send_method); - - // Two special constructors that generate reduced amounts of code at - // LOG call sites for common cases. - - // Used for LOG(INFO): Implied are: - // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. - // - // Using this constructor instead of the more complex constructor above - // saves 19 bytes per call site. - LogMessage(const char* file, int line); - - // Used for LOG(severity) where severity != INFO. Implied - // are: ctr = 0, send_method = &LogMessage::SendToLog - // - // Using this constructor instead of the more complex constructor above - // saves 17 bytes per call site. - LogMessage(const char* file, int line, LogSeverity severity); - - // Constructor to log this message to a specified sink (if not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if - // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise. - LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink, - bool also_send_to_log); - - // Constructor where we also give a vector<string> pointer - // for storing the messages (if the pointer is not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::vector<std::string>* outvec); - - // Constructor where we also give a string pointer for storing the - // message (if the pointer is not NULL). Implied are: ctr = 0, - // send_method = &LogMessage::WriteToStringAndLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::string* message); - - // A special constructor used for check failures - LogMessage(const char* file, int line, const CheckOpString& result); - - ~LogMessage(); - - // Flush a buffered message to the sink set in the constructor. Always - // called by the destructor, it may also be called from elsewhere if - // needed. Only the first call is actioned; any later ones are ignored. - void Flush(); - - // An arbitrary limit on the length of a single log message. This - // is so that streaming can be done more efficiently. - static const size_t kMaxLogMessageLen; - - // Theses should not be called directly outside of logging.*, - // only passed as SendMethod arguments to other LogMessage methods: - void SendToLog(); // Actually dispatch to the logs - void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs - - // Call abort() or similar to perform LOG(FATAL) crash. - static void __declspec(noreturn) Fail(); - - std::ostream& stream(); - - int preserved_errno() const; - - // Must be called without the log_mutex held. (L < log_mutex) - static int64 num_messages(int severity); - - struct LogMessageData; - -private: - // Fully internal SendMethod cases: - void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs - void SendToSink(); // Send to sink if provided, do nothing otherwise. - - // Write to string if provided and dispatch to the logs. - void WriteToStringAndLog(); - - void SaveOrSendToLog(); // Save to stringvec if provided, else to logs - - void Init(const char* file, int line, LogSeverity severity, - void (LogMessage::*send_method)()); - - // Used to fill in crash information during LOG(FATAL) failures. - void RecordCrashReason(glog_internal_namespace_::CrashReason* reason); - - // Counts of messages sent at each priority: - static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex - - // We keep the data in a separate struct so that each instance of - // LogMessage uses less stack space. - LogMessageData* allocated_; - LogMessageData* data_; - - friend class LogDestination; - - LogMessage(const LogMessage&); - void operator=(const LogMessage&); -}; - -// This class happens to be thread-hostile because all instances share -// a single data buffer, but since it can only be created just before -// the process dies, we don't worry so much. -class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { - public: - LogMessageFatal(const char* file, int line); - LogMessageFatal(const char* file, int line, const CheckOpString& result); - __declspec(noreturn) ~LogMessageFatal(); -}; - -// A non-macro interface to the log facility; (useful -// when the logging level is not a compile-time constant). -inline void LogAtLevel(int const severity, std::string const &msg) { - LogMessage(__FILE__, __LINE__, severity).stream() << msg; -} - -// A macro alternative of LogAtLevel. New code may want to use this -// version since there are two advantages: 1. this version outputs the -// file name and the line number where this macro is put like other -// LOG macros, 2. this macro can be used as C++ stream. -#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream() - -// Check if it's compiled in C++11 mode. -// -// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least -// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1 -// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is -// defined according to the language version in effect thereafter. -// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite -// reasonably good C++11 support, so we set LANG_CXX for it and -// newer versions (_MSC_VER >= 1900). -#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ - (defined(_MSC_VER) && _MSC_VER >= 1900)) -// Helper for CHECK_NOTNULL(). -// -// In C++11, all cases can be handled by a single function. Since the value -// category of the argument is preserved (also for rvalue references), -// member initializer lists like the one below will compile correctly: -// -// Foo() -// : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {} -template <typename T> -T CheckNotNull(const char* file, int line, const char* names, T&& t) { - if (t == nullptr) { - LogMessageFatal(file, line, new std::string(names)); - } - return std::forward<T>(t); -} - -#else - -// A small helper for CHECK_NOTNULL(). -template <typename T> -T* CheckNotNull(const char *file, int line, const char *names, T* t) { - if (t == NULL) { - LogMessageFatal(file, line, new std::string(names)); - } - return t; -} -#endif - -// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This -// only works if ostream is a LogStream. If the ostream is not a -// LogStream you'll get an assert saying as much at runtime. -GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, - const PRIVATE_Counter&); - - -// Derived class for PLOG*() above. -class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { - public: - - ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, - void (LogMessage::*send_method)()); - - // Postpends ": strerror(errno) [errno]". - ~ErrnoLogMessage(); - - private: - ErrnoLogMessage(const ErrnoLogMessage&); - void operator=(const ErrnoLogMessage&); -}; - - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". - -class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-safe. -GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-hostile because it ignores -// locking -- used for catastrophic failures. -GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); - -// -// Set the destination to which a particular severity level of log -// messages is sent. If base_filename is "", it means "don't log this -// severity". Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, - const char* base_filename); - -// -// Set the basename of the symlink to the latest log file at a given -// severity. If symlink_basename is empty, do not make a symlink. If -// you don't call this function, the symlink basename is the -// invocation name of the program. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - -// -// Used to send logs to some other kind of destination -// Users should subclass LogSink and override send to do whatever they want. -// Implementations must be thread-safe because a shared instance will -// be called from whichever thread ran the LOG(XXX) line. -class GOOGLE_GLOG_DLL_DECL LogSink { - public: - virtual ~LogSink(); - - // Sink's logging logic (message_len is such as to exclude '\n' at the end). - // This method can't use LOG() or CHECK() as logging system mutex(s) are held - // during this call. - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len, int32 usecs) { - send(severity, full_filename, base_filename, line, - tm_time, message, message_len); - } - // This send() signature is obsolete. - // New implementations should define this in terms of - // the above send() method. - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) = 0; - - // Redefine this to implement waiting for - // the sink's logging logic to complete. - // It will be called after each send() returns, - // but before that LogMessage exits or crashes. - // By default this function does nothing. - // Using this function one can implement complex logic for send() - // that itself involves logging; and do all this w/o causing deadlocks and - // inconsistent rearrangement of log messages. - // E.g. if a LogSink has thread-specific actions, the send() method - // can simply add the message to a queue and wake up another thread that - // handles real logging while itself making some LOG() calls; - // WaitTillSent() can be implemented to wait for that logic to complete. - // See our unittest for an example. - virtual void WaitTillSent(); - - // Returns the normal text output of the log message. - // Can be useful to implement send(). - static std::string ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len, - int32 usecs); - - // Obsolete - static std::string ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) { - return ToString(severity, file, line, tm_time, message, message_len, 0); - } -}; - -// Add or remove a LogSink as a consumer of logging data. Thread-safe. -GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); -GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); - -// -// Specify an "extension" added to the filename specified via -// SetLogDestination. This applies to all severity levels. It's -// often used to append the port we're listening on to the logfile -// name. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( - const char* filename_extension); - -// -// Make it so that all log messages of at least a particular severity -// are logged to stderr (in addition to logging to the usual log -// file(s)). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); - -// -// Make it so that all log messages go only to stderr. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void LogToStderr(); - -// -// Make it so that all log messages of at least a particular severity are -// logged via email to a list of addresses (in addition to logging to the -// usual log file(s)). The list of addresses is just a string containing -// the email addresses to send to (separated by spaces, say). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, - const char* addresses); - -// A simple function that sends email. dest is a commma-separated -// list of addressess. Thread-safe. -GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, - const char *subject, const char *body); - -GOOGLE_GLOG_DLL_DECL const std::vector<std::string>& GetLoggingDirectories(); - -// For tests only: Clear the internal [cached] list of logging directories to -// force a refresh the next time GetLoggingDirectories is called. -// Thread-hostile. -void TestOnly_ClearLoggingDirectoriesList(); - -// Returns a set of existing temporary directories, which will be a -// subset of the directories returned by GetLogginDirectories(). -// Thread-safe. -GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( - std::vector<std::string>* list); - -// Print any fatal message again -- useful to call from signal handler -// so that the last thing in the output is the fatal message. -// Thread-hostile, but a race is unlikely. -GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); - -// Truncate a log file that may be the append-only output of multiple -// processes and hence can't simply be renamed/reopened (typically a -// stdout/stderr). If the file "path" is > "limit" bytes, copy the -// last "keep" bytes to offset 0 and truncate the rest. Since we could -// be racing with other writers, this approach has the potential to -// lose very small amounts of data. For security, only follow symlinks -// if the path is /proc/self/fd/* -GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, - int64 limit, int64 keep); - -// Truncate stdout and stderr if they are over the value specified by -// --max_log_size; keep the final 1MB. This function has the same -// race condition as TruncateLogFile. -GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); - -// Return the string representation of the provided LogSeverity level. -// Thread-safe. -GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); - -// --------------------------------------------------------------------- -// Implementation details that are not useful to most clients -// --------------------------------------------------------------------- - -// A Logger is the interface used by logging modules to emit entries -// to a log. A typical implementation will dump formatted data to a -// sequence of files. We also provide interfaces that will forward -// the data to another thread so that the invoker never blocks. -// Implementations should be thread-safe since the logging system -// will write to them from multiple threads. - -namespace base { - -class GOOGLE_GLOG_DLL_DECL Logger { - public: - virtual ~Logger(); - - // Writes "message[0,message_len-1]" corresponding to an event that - // occurred at "timestamp". If "force_flush" is true, the log file - // is flushed immediately. - // - // The input message has already been formatted as deemed - // appropriate by the higher level logging facility. For example, - // textual log messages already contain timestamps, and the - // file:linenumber header. - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) = 0; - - // Flush any buffered messages - virtual void Flush() = 0; - - // Get the current LOG file size. - // The returned value is approximate since some - // logged data may not have been flushed to disk yet. - virtual uint32 LogSize() = 0; -}; - -// Get the logger for the specified severity level. The logger -// remains the property of the logging module and should not be -// deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); - -// Set the logger for the specified severity level. The logger -// becomes the property of the logging module and should not -// be deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); - -} - -// glibc has traditionally implemented two incompatible versions of -// strerror_r(). There is a poorly defined convention for picking the -// version that we want, but it is not clear whether it even works with -// all versions of glibc. -// So, instead, we provide this wrapper that automatically detects the -// version that is in use, and then implements POSIX semantics. -// N.B. In addition to what POSIX says, we also guarantee that "buf" will -// be set to an empty string, if this function failed. This means, in most -// cases, you do not need to check the error code and you can directly -// use the value of "buf". It will never have an undefined value. -// DEPRECATED: Use StrError(int) instead. -GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); - -// A thread-safe replacement for strerror(). Returns a string describing the -// given POSIX error code. -GOOGLE_GLOG_DLL_DECL std::string StrError(int err); - -// A class for which we define operator<<, which does nothing. -class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { - public: - // Initialize the LogStream so the messages can be written somewhere - // (they'll never be actually displayed). This will be needed if a - // NullStream& is implicitly converted to LogStream&, in which case - // the overloaded NullStream::operator<< will not be invoked. - NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream(const char* /*file*/, int /*line*/, - const CheckOpString& /*result*/) : - LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream &stream() { return *this; } - private: - // A very short buffer for messages (which we discard anyway). This - // will be needed if NullStream& converted to LogStream& (e.g. as a - // result of a conditional expression). - char message_buffer_[2]; -}; - -// Do nothing. This operator is inline, allowing the message to be -// compiled away. The message will not be compiled away if we do -// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when -// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly -// converted to LogStream and the message will be computed and then -// quietly discarded. -template<class T> -inline NullStream& operator<<(NullStream &str, const T &) { return str; } - -// Similar to NullStream, but aborts the program (without stack -// trace), like LogMessageFatal. -class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { - public: - NullStreamFatal() { } - NullStreamFatal(const char* file, int line, const CheckOpString& result) : - NullStream(file, line, result) { } - __declspec(noreturn) ~NullStreamFatal() throw () { _exit(1); } -}; - -// Install a signal handler that will dump signal information and a stack -// trace when the program crashes on certain signals. We'll install the -// signal handler for the following signals. -// -// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. -// -// By default, the signal handler will write the failure dump to the -// standard error. You can customize the destination by installing your -// own writer function by InstallFailureWriter() below. -// -// Note on threading: -// -// The function should be called before threads are created, if you want -// to use the failure signal handler for all threads. The stack trace -// will be shown only for the thread that receives the signal. In other -// words, stack traces of other threads won't be shown. -GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); - -// Installs a function that is used for writing the failure dump. "data" -// is the pointer to the beginning of a message to be written, and "size" -// is the size of the message. You should not expect the data is -// terminated with '\0'. -GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( - void (*writer)(const char* data, int size)); - -} - -#endif // _LOGGING_H_ diff --git a/third_party/glog/src/windows/glog/raw_logging.h b/third_party/glog/src/windows/glog/raw_logging.h deleted file mode 100755 index e0e6d6f1a256..000000000000 --- a/third_party/glog/src/windows/glog/raw_logging.h +++ /dev/null @@ -1,184 +0,0 @@ -// This file is automatically generated from src/glog/raw_logging.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Maxim Lifantsev -// -// Thread-safe logging routines that do not allocate any memory or -// acquire any locks, and can therefore be used by low-level memory -// allocation and synchronization code. - -#ifndef BASE_RAW_LOGGING_H_ -#define BASE_RAW_LOGGING_H_ - -#include <time.h> - -namespace google { - -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// This is similar to LOG(severity) << format... and VLOG(level) << format.., -// but -// * it is to be used ONLY by low-level modules that can't use normal LOG() -// * it is desiged to be a low-level logger that does not allocate any -// memory and does not need any locks, hence: -// * it logs straight and ONLY to STDERR w/o buffering -// * it uses an explicit format and arguments list -// * it will silently chop off really long message strings -// Usage example: -// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); -// RAW_VLOG(3, "status is %i", status); -// These will print an almost standard log lines like this to stderr only: -// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file -// I0821 211317 file.cc:142] RAW: status is 20 -#define RAW_LOG(severity, ...) \ - do { \ - switch (google::GLOG_ ## severity) { \ - case 0: \ - RAW_LOG_INFO(__VA_ARGS__); \ - break; \ - case 1: \ - RAW_LOG_WARNING(__VA_ARGS__); \ - break; \ - case 2: \ - RAW_LOG_ERROR(__VA_ARGS__); \ - break; \ - case 3: \ - RAW_LOG_FATAL(__VA_ARGS__); \ - break; \ - default: \ - break; \ - } \ - } while (0) - -// The following STRIP_LOG testing is performed in the header file so that it's -// possible to completely compile out the logging code and the log messages. -#if STRIP_LOG == 0 -#define RAW_VLOG(verboselevel, ...) \ - do { \ - if (VLOG_IS_ON(verboselevel)) { \ - RAW_LOG_INFO(__VA_ARGS__); \ - } \ - } while (0) -#else -#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG == 0 -#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG <= 1 -#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 1 - -#if STRIP_LOG <= 2 -#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 2 - -#if STRIP_LOG <= 3 -#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(1); \ - } while (0) -#endif // STRIP_LOG <= 3 - -// Similar to CHECK(condition) << message, -// but for low-level modules: we use only RAW_LOG that does not allocate memory. -// We do not want to provide args list here to encourage this usage: -// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); -// so that the args are not computed when not needed. -#define RAW_CHECK(condition, message) \ - do { \ - if (!(condition)) { \ - RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ - } \ - } while (0) - -// Debug versions of RAW_LOG and RAW_CHECK -#ifndef NDEBUG - -#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) - -#else // NDEBUG - -#define RAW_DLOG(severity, ...) \ - while (false) \ - RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) \ - while (false) \ - RAW_CHECK(condition, message) - -#endif // NDEBUG - -// Stub log function used to work around for unused variable warnings when -// building with STRIP_LOG > 0. -static inline void RawLogStub__(int /* ignored */, ...) { -} - -// Helper function to implement RAW_LOG and RAW_VLOG -// Logs format... at "severity" level, reporting it -// as called from file:line. -// This does not allocate memory or acquire locks. -GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, - const char* file, - int line, - const char* format, ...) - ; - -} - -#endif // BASE_RAW_LOGGING_H_ diff --git a/third_party/glog/src/windows/glog/stl_logging.h b/third_party/glog/src/windows/glog/stl_logging.h deleted file mode 100755 index a97a90895959..000000000000 --- a/third_party/glog/src/windows/glog/stl_logging.h +++ /dev/null @@ -1,224 +0,0 @@ -// This file is automatically generated from src/glog/stl_logging.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 2003, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Stream output operators for STL containers; to be used for logging *only*. -// Inclusion of this file lets you do: -// -// list<string> x; -// LOG(INFO) << "data: " << x; -// vector<int> v1, v2; -// CHECK_EQ(v1, v2); -// -// If you want to use this header file with hash_compare maps or slist, you -// need to define macros before including this file: -// -// - GLOG_STL_LOGGING_FOR_UNORDERED - <unordered_map> and <unordered_set> -// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)> -// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)> -// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <ext/slist> -// - -#ifndef UTIL_GTL_STL_LOGGING_INL_H_ -#define UTIL_GTL_STL_LOGGING_INL_H_ - -#if !1 -# error We do not support stl_logging for this compiler -#endif - -#include <deque> -#include <list> -#include <map> -#include <ostream> -#include <set> -#include <utility> -#include <vector> - -#ifdef GLOG_STL_LOGGING_FOR_UNORDERED -# include <unordered_map> -# include <unordered_set> -#endif - -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# include <tr1/unordered_map> -# include <tr1/unordered_set> -#endif - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -# include <ext/hash_set> -# include <ext/hash_map> -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST -# include <ext/slist> -#endif - -// Forward declare these two, and define them after all the container streams -// operators so that we can recurse from pair -> container -> container -> pair -// properly. -template<class First, class Second> -std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p); - -namespace google { - -template<class Iter> -void PrintSequence(std::ostream& out, Iter begin, Iter end); - -} - -#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ -template<class T1, class T2> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2>& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_TWO_ARG_CONTAINER(std::vector) -OUTPUT_TWO_ARG_CONTAINER(std::deque) -OUTPUT_TWO_ARG_CONTAINER(std::list) -#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST -OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist) -#endif - -#undef OUTPUT_TWO_ARG_CONTAINER - -#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \ -template<class T1, class T2, class T3> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2, T3>& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_THREE_ARG_CONTAINER(std::set) -OUTPUT_THREE_ARG_CONTAINER(std::multiset) - -#undef OUTPUT_THREE_ARG_CONTAINER - -#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \ -template<class T1, class T2, class T3, class T4> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2, T3, T4>& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_FOUR_ARG_CONTAINER(std::map) -OUTPUT_FOUR_ARG_CONTAINER(std::multimap) -#ifdef GLOG_STL_LOGGING_FOR_UNORDERED -OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set) -OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset) -#endif -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set) -OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset) -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set) -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset) -#endif - -#undef OUTPUT_FOUR_ARG_CONTAINER - -#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \ -template<class T1, class T2, class T3, class T4, class T5> \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence<T1, T2, T3, T4, T5>& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -#ifdef GLOG_STL_LOGGING_FOR_UNORDERED -OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map) -OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap) -#endif -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map) -OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap) -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map) -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap) -#endif - -#undef OUTPUT_FIVE_ARG_CONTAINER - -template<class First, class Second> -inline std::ostream& operator<<(std::ostream& out, - const std::pair<First, Second>& p) { - out << '(' << p.first << ", " << p.second << ')'; - return out; -} - -namespace google { - -template<class Iter> -inline void PrintSequence(std::ostream& out, Iter begin, Iter end) { - // Output at most 100 elements -- appropriate if used for logging. - for (int i = 0; begin != end && i < 100; ++i, ++begin) { - if (i > 0) out << ' '; - out << *begin; - } - if (begin != end) { - out << " ..."; - } -} - -} - -// Note that this is technically undefined behavior! We are adding things into -// the std namespace for a reason though -- we are providing new operations on -// types which are themselves defined with this namespace. Without this, these -// operator overloads cannot be found via ADL. If these definitions are not -// found via ADL, they must be #included before they're used, which requires -// this header to be included before apparently independent other headers. -// -// For example, base/logging.h defines various template functions to implement -// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails. -// It does so via the function template MakeCheckOpValueString: -// template<class T> -// void MakeCheckOpValueString(strstream* ss, const T& v) { -// (*ss) << v; -// } -// Because 'glog/logging.h' is included before 'glog/stl_logging.h', -// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only -// find these operator definitions via ADL. -// -// Even this solution has problems -- it may pull unintended operators into the -// namespace as well, allowing them to also be found via ADL, and creating code -// that only works with a particular order of includes. Long term, we need to -// move all of the *definitions* into namespace std, bet we need to ensure no -// one references them first. This lets us take that step. We cannot define them -// in both because that would create ambiguous overloads when both are found. -namespace std { using ::operator<<; } - -#endif // UTIL_GTL_STL_LOGGING_INL_H_ diff --git a/third_party/glog/src/windows/glog/vlog_is_on.h b/third_party/glog/src/windows/glog/vlog_is_on.h deleted file mode 100755 index 409a4011b385..000000000000 --- a/third_party/glog/src/windows/glog/vlog_is_on.h +++ /dev/null @@ -1,133 +0,0 @@ -// This file is automatically generated from src/glog/vlog_is_on.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 1999, 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Ray Sidney and many others -// -// Defines the VLOG_IS_ON macro that controls the variable-verbosity -// conditional logging. -// -// It's used by VLOG and VLOG_IF in logging.h -// and by RAW_VLOG in raw_logging.h to trigger the logging. -// -// It can also be used directly e.g. like this: -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished e.g. via just VLOG(2) << ...; -// } -// -// The truth value that VLOG_IS_ON(level) returns is determined by -// the three verbosity level flags: -// --v=<n> Gives the default maximal active V-logging level; -// 0 is the default. -// Normally positive values are used for V-logging levels. -// --vmodule=<str> Gives the per-module maximal V-logging levels to override -// the value given by --v. -// E.g. "my_module=2,foo*=3" would change the logging level -// for all code in source files "my_module.*" and "foo*.*" -// ("-inl" suffixes are also disregarded for this matching). -// -// SetVLOGLevel helper function is provided to do limited dynamic control over -// V-logging by overriding the per-module settings given via --vmodule flag. -// -// CAVEAT: --vmodule functionality is not available in non gcc compilers. -// - -#ifndef BASE_VLOG_IS_ON_H_ -#define BASE_VLOG_IS_ON_H_ - -#include "glog/log_severity.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -#if defined(__GNUC__) -// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. -// (Normally) the first time every VLOG_IS_ON(n) site is hit, -// we determine what variable will dynamically control logging at this site: -// it's either FLAGS_v or an appropriate internal variable -// matching the current source file that represents results of -// parsing of --vmodule flag and/or SetVLOGLevel calls. -#define VLOG_IS_ON(verboselevel) \ - __extension__ \ - ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \ - google::int32 verbose_level__ = (verboselevel); \ - (*vlocal__ >= verbose_level__) && \ - ((vlocal__ != &google::kLogSiteUninitialized) || \ - (google::InitVLOG3__(&vlocal__, &FLAGS_v, \ - __FILE__, verbose_level__))); }) -#else -// GNU extensions not available, so we do not support --vmodule. -// Dynamic value of FLAGS_v always controls the logging level. -#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) -#endif - -// Set VLOG(_IS_ON) level for module_pattern to log_level. -// This lets us dynamically control what is normally set by the --vmodule flag. -// Returns the level that previously applied to module_pattern. -// NOTE: To change the log level for VLOG(_IS_ON) sites -// that have already executed after/during InitGoogleLogging, -// one needs to supply the exact --vmodule pattern that applied to them. -// (If no --vmodule pattern applied to them -// the value of FLAGS_v will continue to control them.) -extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, - int log_level); - -// Various declarations needed for VLOG_IS_ON above: ========================= - -// Special value used to indicate that a VLOG_IS_ON site has not been -// initialized. We make this a large value, so the common-case check -// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition -// passes in such cases and InitVLOG3__ is then triggered. -extern google::int32 kLogSiteUninitialized; - -// Helper routine which determines the logging info for a particalur VLOG site. -// site_flag is the address of the site-local pointer to the controlling -// verbosity level -// site_default is the default to use for *site_flag -// fname is the current source file name -// verbose_level is the argument to VLOG_IS_ON -// We will return the return value for VLOG_IS_ON -// and if possible set *site_flag appropriately. -extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( - google::int32** site_flag, - google::int32* site_default, - const char* fname, - google::int32 verbose_level); - -#endif // BASE_VLOG_IS_ON_H_ diff --git a/third_party/glog/src/windows/port.cc b/third_party/glog/src/windows/port.cc deleted file mode 100755 index 19bda367c62b..000000000000 --- a/third_party/glog/src/windows/port.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2008, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * --- - * Author: Craig Silverstein - * Copied from google-perftools and modified by Shinichiro Hamaji - */ - -#ifndef _WIN32 -# error You should only be including windows/port.cc in a windows environment! -#endif - -#include "config.h" -#include <stdarg.h> // for va_list, va_start, va_end -#include "port.h" - -// These call the windows _vsnprintf, but always NUL-terminate. -int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { - if (size == 0) // not even room for a \0? - return -1; // not what C99 says to do, but what windows does - str[size-1] = '\0'; - return _vsnprintf(str, size-1, format, ap); -} - -#ifndef HAVE_LOCALTIME_R -struct tm* localtime_r(const time_t* timep, struct tm* result) { - localtime_s(result, timep); - return result; -} -#endif // not HAVE_LOCALTIME_R -#ifndef HAVE_SNPRINTF -int snprintf(char *str, size_t size, const char *format, ...) { - va_list ap; - va_start(ap, format); - const int r = vsnprintf(str, size, format, ap); - va_end(ap); - return r; -} -#endif diff --git a/third_party/glog/src/windows/port.h b/third_party/glog/src/windows/port.h deleted file mode 100755 index 7b4b9c8545b8..000000000000 --- a/third_party/glog/src/windows/port.h +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (c) 2008, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * --- - * Author: Craig Silverstein - * Copied from google-perftools and modified by Shinichiro Hamaji - * - * These are some portability typedefs and defines to make it a bit - * easier to compile this code under VC++. - * - * Several of these are taken from glib: - * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html - */ - -#ifndef CTEMPLATE_WINDOWS_PORT_H_ -#define CTEMPLATE_WINDOWS_PORT_H_ - -#include "config.h" - -#ifdef _WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ -#endif - -#include <windows.h> -#include <winsock.h> /* for gethostname */ -#include <io.h> /* because we so often use open/close/etc */ -#include <direct.h> /* for _getcwd() */ -#include <process.h> /* for _getpid() */ -#include <stdio.h> /* read in vsnprintf decl. before redifining it */ -#include <stdarg.h> /* template_dictionary.cc uses va_copy */ -#include <string.h> /* for _strnicmp(), strerror_s() */ -#include <time.h> /* 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. - */ - -#ifdef _MSC_VER - -/* 4244: otherwise we get problems when substracting two size_t's to an int - * 4251: it's complaining about a private struct I've chosen not to dllexport - * 4355: we use this in a constructor, but we do it safely - * 4715: for some reason VC++ stopped realizing you can't return after abort() - * 4800: we know we're casting ints/char*'s to bools, and we're ok with that - * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() - * 4312: Converting uint32_t to a pointer when testing %p - * 4267: also subtracting two size_t to int - * 4722: Destructor never returns due to abort() - */ -#pragma warning(disable:4244 4251 4355 4715 4800 4996 4267 4312 4722) - -/* file I/O */ -#define PATH_MAX 1024 -#define access _access -#define getcwd _getcwd -#define open _open -#define read _read -#define write _write -#define lseek _lseek -#define close _close -#define popen _popen -#define pclose _pclose -#define R_OK 04 /* read-only (for access()) */ -#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) - -#define O_WRONLY _O_WRONLY -#define O_CREAT _O_CREAT -#define O_EXCL _O_EXCL - -#ifndef __MINGW32__ -enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; -#endif -#define S_IRUSR S_IREAD -#define S_IWUSR S_IWRITE - -/* Not quite as lightweight as a hard-link, but more than good enough for us. */ -#define link(oldpath, newpath) CopyFileA(oldpath, newpath, false) - -#define strcasecmp _stricmp -#define strncasecmp _strnicmp - -/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */ -/* VC11 provides std::hash */ -#if defined(_MSC_VER) && (_MSC_VER < 1700) -#define hash hash_compare -#endif - -/* Sleep is in ms, on windows */ -#define sleep(secs) Sleep((secs) * 1000) - -/* We can't just use _vsnprintf and _snprintf as drop-in-replacements, - * because they don't always NUL-terminate. :-( We also can't use the - * name vsnprintf, since windows defines that (but not snprintf (!)). - */ -#ifndef HAVE_SNPRINTF -extern int GOOGLE_GLOG_DLL_DECL snprintf(char *str, size_t size, - const char *format, ...); -#endif -extern int GOOGLE_GLOG_DLL_DECL safe_vsnprintf(char *str, size_t size, - const char *format, va_list ap); -#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) -#ifndef va_copy -#define va_copy(dst, src) (dst) = (src) -#endif - -/* Windows doesn't support specifying the number of buckets as a - * hash_map constructor arg, so we leave this blank. - */ -#define CTEMPLATE_SMALL_HASHTABLE - -#define DEFAULT_TEMPLATE_ROOTDIR ".." - -// ----------------------------------- SYSTEM/PROCESS -typedef int pid_t; -#define getpid _getpid - -#endif // _MSC_VER - -// ----------------------------------- THREADS -#if defined(HAVE_PTHREAD) -# include <pthread.h> -#else // no PTHREAD -typedef DWORD pthread_t; -typedef DWORD pthread_key_t; -typedef LONG pthread_once_t; -enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock -#define pthread_self GetCurrentThreadId -#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) -#endif // HAVE_PTHREAD - -#ifndef HAVE_LOCALTIME_R -extern GOOGLE_GLOG_DLL_DECL struct tm* localtime_r(const time_t* timep, struct tm* result); -#endif // not HAVE_LOCALTIME_R - -inline char* strerror_r(int errnum, char* buf, size_t buflen) { - strerror_s(buf, buflen, errnum); - return buf; -} - -#ifndef __cplusplus -/* I don't see how to get inlining for C code in MSVC. Ah well. */ -#define inline -#endif - -#endif /* _WIN32 */ - -#endif /* CTEMPLATE_WINDOWS_PORT_H_ */ diff --git a/third_party/glog/src/windows/preprocess.sh b/third_party/glog/src/windows/preprocess.sh deleted file mode 100755 index c35e92913b65..000000000000 --- a/third_party/glog/src/windows/preprocess.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# --- -# Author: Craig Silverstein -# Copied from google-perftools and modified by Shinichiro Hamaji -# -# This script is meant to be run at distribution-generation time, for -# instance by autogen.sh. It does some of the work configure would -# normally do, for windows systems. In particular, it expands all the -# @...@ variables found in .in files, and puts them here, in the windows -# directory. -# -# This script should be run before any new release. - -if [ -z "$1" ]; then - echo "USAGE: $0 <src/ directory>" - exit 1 -fi - -DLLDEF_MACRO_NAME="GLOG_DLL_DECL" - -# The text we put in every .h files we create. As a courtesy, we'll -# include a helpful comment for windows users as to how to use -# GLOG_DLL_DECL. Apparently sed expands \n into a newline. Good! -DLLDEF_DEFINES="\ -// NOTE: if you are statically linking the template library into your binary\n\ -// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\ -// as a compiler flag in your project file to turn off the dllimports.\n\ -#ifndef $DLLDEF_MACRO_NAME\n\ -# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\ -#endif" - -# Read all the windows config info into variables -# In order for the 'set' to take, this requires putting all in a subshell. -( - while read define varname value; do - [ "$define" != "#define" ] && continue - eval "$varname='$value'" - done - - # Process all the .in files in the "glog" subdirectory - mkdir -p "$1/windows/glog" - for file in `echo "$1"/glog/*.in`; do - echo "Processing $file" - outfile="$1/windows/glog/`basename $file .in`" - - echo "\ -// This file is automatically generated from $file -// using src/windows/preprocess.sh. -// DO NOT EDIT! -" > "$outfile" - # Besides replacing @...@, we also need to turn on dllimport - # We also need to replace hash by hash_compare (annoying we hard-code :-( ) - sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \ - -e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \ - -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \ - -e "s!@ac_cv_cxx_hash_namespace@!$HASH_NAMESPACE!g" \ - -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \ - -e "s!@ac_cv_have_stdint_h@!0!g" \ - -e "s!@ac_cv_have_systypes_h@!0!g" \ - -e "s!@ac_cv_have_inttypes_h@!0!g" \ - -e "s!@ac_cv_have_unistd_h@!0!g" \ - -e "s!@ac_cv_have_uint16_t@!0!g" \ - -e "s!@ac_cv_have_u_int16_t@!0!g" \ - -e "s!@ac_cv_have___uint16@!1!g" \ - -e "s!@ac_cv_have_libgflags@!0!g" \ - -e "s!@ac_cv_have___builtin_expect@!0!g" \ - -e "s!@ac_cv_cxx_using_operator@!1!g" \ - -e "s!@ac_cv___attribute___noreturn@!__declspec(noreturn)!g" \ - -e "s!@ac_cv___attribute___noinline@!!g" \ - -e "s!@ac_cv___attribute___printf_4_5@!!g" \ - -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \ - -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \ - -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \ - -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \ - -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \ - -e "s!\\bhash\\b!hash_compare!g" \ - "$file" >> "$outfile" - done -) < "$1/windows/config.h" - -# log_severity.h isn't a .in file. -echo "\ -// This file is automatically generated from $1/glog/log_severity.h -// using src/windows/preprocess.sh. -// DO NOT EDIT! -" > "$1/windows/glog/log_severity.h" -cat "$1/glog/log_severity.h" >> "$1/windows/glog/log_severity.h" - -echo "DONE" |