Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2005, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // ---
     31 // This file contains #include information about logging-related stuff.
     32 // Pretty much everybody needs to #include this file so that they can
     33 // log various happenings.
     34 //
     35 #ifndef _LOGGING_H_
     36 #define _LOGGING_H_
     37 
     38 #include <config.h>
     39 #include <stdarg.h>
     40 #include <stdlib.h>
     41 #include <stdio.h>
     42 #ifdef HAVE_UNISTD_H
     43 #include <unistd.h>    // for write()
     44 #endif
     45 #include <string.h>    // for strlen(), strcmp()
     46 #include <assert.h>
     47 #include <errno.h>     // for errno
     48 #include "base/commandlineflags.h"
     49 
     50 // On some systems (like freebsd), we can't call write() at all in a
     51 // global constructor, perhaps because errno hasn't been set up.
     52 // (In windows, we can't call it because it might call malloc.)
     53 // Calling the write syscall is safer (it doesn't set errno), so we
     54 // prefer that.  Note we don't care about errno for logging: we just
     55 // do logging on a best-effort basis.
     56 #if defined(_MSC_VER)
     57 #define WRITE_TO_STDERR(buf, len) WriteToStderr(buf, len);  // in port.cc
     58 #elif defined(HAVE_SYS_SYSCALL_H)
     59 #include <sys/syscall.h>
     60 #define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len)
     61 #else
     62 #define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len)
     63 #endif
     64 
     65 // MSVC and mingw define their own, safe version of vnsprintf (the
     66 // windows one in broken) in port.cc.  Everyone else can use the
     67 // version here.  We had to give it a unique name for windows.
     68 #ifndef _WIN32
     69 # define perftools_vsnprintf vsnprintf
     70 #endif
     71 
     72 
     73 // We log all messages at this log-level and below.
     74 // INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4
     75 DECLARE_int32(verbose);
     76 
     77 // CHECK dies with a fatal error if condition is not true.  It is *not*
     78 // controlled by NDEBUG, so the check will be executed regardless of
     79 // compilation mode.  Therefore, it is safe to do things like:
     80 //    CHECK(fp->Write(x) == 4)
     81 // Note we use write instead of printf/puts to avoid the risk we'll
     82 // call malloc().
     83 #define CHECK(condition)                                                \
     84   do {                                                                  \
     85     if (!(condition)) {                                                 \
     86       WRITE_TO_STDERR("Check failed: " #condition "\n",                 \
     87                       sizeof("Check failed: " #condition "\n")-1);      \
     88       abort();                                                          \
     89     }                                                                   \
     90   } while (0)
     91 
     92 // This takes a message to print.  The name is historical.
     93 #define RAW_CHECK(condition, message)                                          \
     94   do {                                                                         \
     95     if (!(condition)) {                                                        \
     96       WRITE_TO_STDERR("Check failed: " #condition ": " message "\n",           \
     97                       sizeof("Check failed: " #condition ": " message "\n")-1);\
     98       abort();                                                                 \
     99     }                                                                          \
    100   } while (0)
    101 
    102 // This is like RAW_CHECK, but only in debug-mode
    103 #ifdef NDEBUG
    104 enum { DEBUG_MODE = 0 };
    105 #define RAW_DCHECK(condition, message)
    106 #else
    107 enum { DEBUG_MODE = 1 };
    108 #define RAW_DCHECK(condition, message)  RAW_CHECK(condition, message)
    109 #endif
    110 
    111 // This prints errno as well.  Note we use write instead of printf/puts to
    112 // avoid the risk we'll call malloc().
    113 #define PCHECK(condition)                                               \
    114   do {                                                                  \
    115     if (!(condition)) {                                                 \
    116       const int err_no = errno;                                         \
    117       WRITE_TO_STDERR("Check failed: " #condition ": ",                 \
    118                       sizeof("Check failed: " #condition ": ")-1);      \
    119       WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no)));      \
    120       WRITE_TO_STDERR("\n", sizeof("\n")-1);                            \
    121       abort();                                                          \
    122     }                                                                   \
    123   } while (0)
    124 
    125 // Helper macro for binary operators; prints the two values on error
    126 // Don't use this macro directly in your code, use CHECK_EQ et al below
    127 
    128 // WARNING: These don't compile correctly if one of the arguments is a pointer
    129 // and the other is NULL. To work around this, simply static_cast NULL to the
    130 // type of the desired pointer.
    131 
    132 // TODO(jandrews): Also print the values in case of failure.  Requires some
    133 // sort of type-sensitive ToString() function.
    134 #define CHECK_OP(op, val1, val2)                                        \
    135   do {                                                                  \
    136     if (!((val1) op (val2))) {                                          \
    137       fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
    138       abort();                                                          \
    139     }                                                                   \
    140   } while (0)
    141 
    142 #define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
    143 #define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
    144 #define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
    145 #define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
    146 #define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
    147 #define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
    148 
    149 // Synonyms for CHECK_* that are used in some unittests.
    150 #define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
    151 #define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
    152 #define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
    153 #define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
    154 #define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
    155 #define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
    156 #define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
    157 #define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
    158 #define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
    159 #define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
    160 #define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
    161 #define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
    162 // As are these variants.
    163 #define EXPECT_TRUE(cond)     CHECK(cond)
    164 #define EXPECT_FALSE(cond)    CHECK(!(cond))
    165 #define EXPECT_STREQ(a, b)    CHECK(strcmp(a, b) == 0)
    166 #define ASSERT_TRUE(cond)     EXPECT_TRUE(cond)
    167 #define ASSERT_FALSE(cond)    EXPECT_FALSE(cond)
    168 #define ASSERT_STREQ(a, b)    EXPECT_STREQ(a, b)
    169 
    170 // Used for (libc) functions that return -1 and set errno
    171 #define CHECK_ERR(invocation)  PCHECK((invocation) != -1)
    172 
    173 // A few more checks that only happen in debug mode
    174 #ifdef NDEBUG
    175 #define DCHECK_EQ(val1, val2)
    176 #define DCHECK_NE(val1, val2)
    177 #define DCHECK_LE(val1, val2)
    178 #define DCHECK_LT(val1, val2)
    179 #define DCHECK_GE(val1, val2)
    180 #define DCHECK_GT(val1, val2)
    181 #else
    182 #define DCHECK_EQ(val1, val2)  CHECK_EQ(val1, val2)
    183 #define DCHECK_NE(val1, val2)  CHECK_NE(val1, val2)
    184 #define DCHECK_LE(val1, val2)  CHECK_LE(val1, val2)
    185 #define DCHECK_LT(val1, val2)  CHECK_LT(val1, val2)
    186 #define DCHECK_GE(val1, val2)  CHECK_GE(val1, val2)
    187 #define DCHECK_GT(val1, val2)  CHECK_GT(val1, val2)
    188 #endif
    189 
    190 
    191 #ifdef ERROR
    192 #undef ERROR      // may conflict with ERROR macro on windows
    193 #endif
    194 enum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};
    195 
    196 // NOTE: we add a newline to the end of the output if it's not there already
    197 inline void LogPrintf(int severity, const char* pat, va_list ap) {
    198   // We write directly to the stderr file descriptor and avoid FILE
    199   // buffering because that may invoke malloc()
    200   char buf[600];
    201   perftools_vsnprintf(buf, sizeof(buf)-1, pat, ap);
    202   if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') {
    203     assert(strlen(buf)+1 < sizeof(buf));
    204     strcat(buf, "\n");
    205   }
    206   WRITE_TO_STDERR(buf, strlen(buf));
    207   if ((severity) == FATAL)
    208     abort(); // LOG(FATAL) indicates a big problem, so don't run atexit() calls
    209 }
    210 
    211 // Note that since the order of global constructors is unspecified,
    212 // global code that calls RAW_LOG may execute before FLAGS_verbose is set.
    213 // Such code will run with verbosity == 0 no matter what.
    214 #define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)
    215 
    216 // In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it.
    217 #define LOG_PRINTF(severity, pat) do {          \
    218   if (VLOG_IS_ON(severity)) {                   \
    219     va_list ap;                                 \
    220     va_start(ap, pat);                          \
    221     LogPrintf(severity, pat, ap);               \
    222     va_end(ap);                                 \
    223   }                                             \
    224 } while (0)
    225 
    226 // RAW_LOG is the main function; some synonyms are used in unittests.
    227 inline void RAW_LOG(int lvl, const char* pat, ...)  { LOG_PRINTF(lvl, pat); }
    228 inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
    229 inline void LOG(int lvl, const char* pat, ...)      { LOG_PRINTF(lvl, pat); }
    230 inline void VLOG(int lvl, const char* pat, ...)     { LOG_PRINTF(lvl, pat); }
    231 inline void LOG_IF(int lvl, bool cond, const char* pat, ...) {
    232   if (cond)  LOG_PRINTF(lvl, pat);
    233 }
    234 
    235 // This isn't technically logging, but it's also IO and also is an
    236 // attempt to be "raw" -- that is, to not use any higher-level libc
    237 // routines that might allocate memory or (ideally) try to allocate
    238 // locks.  We use an opaque file handle (not necessarily an int)
    239 // to allow even more low-level stuff in the future.
    240 // Like other "raw" routines, these functions are best effort, and
    241 // thus don't return error codes (except RawOpenForWriting()).
    242 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
    243 #ifndef NOMINMAX
    244 #define NOMINMAX     // @#!$& windows
    245 #endif
    246 #include <windows.h>
    247 typedef HANDLE RawFD;
    248 const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;
    249 #else
    250 typedef int RawFD;
    251 const RawFD kIllegalRawFD = -1;   // what open returns if it fails
    252 #endif  // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
    253 
    254 RawFD RawOpenForWriting(const char* filename);   // uses default permissions
    255 void RawWrite(RawFD fd, const char* buf, size_t len);
    256 void RawClose(RawFD fd);
    257 
    258 #endif // _LOGGING_H_
    259