logging.h revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2005, Google Inc.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains #include information about logging-related stuff.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pretty much everybody needs to #include this file so that they can
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// log various happenings.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _LOGGING_H_
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _LOGGING_H_
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <config.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_UNISTD_H
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>    // for write()
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>    // for strlen(), strcmp()
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>     // for errno
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/abort.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/commandlineflags.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On some systems (like freebsd), we can't call write() at all in a
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// global constructor, perhaps because errno hasn't been set up.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (In windows, we can't call it because it might call malloc.)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calling the write syscall is safer (it doesn't set errno), so we
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prefer that.  Note we don't care about errno for logging: we just
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do logging on a best-effort basis.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WRITE_TO_STDERR(buf, len) WriteToStderr(buf, len);  // in port.cc
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#elif defined(__ANDROID__) || defined(ANDROID)
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include <android/log.h>
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#define WRITE_TO_STDERR(buf, len) \
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    __android_log_write(ANDROID_LOG_ERROR, "gperftools", buf)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(HAVE_SYS_SYSCALL_H)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/syscall.h>
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC and mingw define their own, safe version of vnsprintf (the
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// windows one in broken) in port.cc.  Everyone else can use the
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// version here.  We had to give it a unique name for windows.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _WIN32
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define perftools_vsnprintf vsnprintf
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We log all messages at this log-level and below.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_int32(verbose);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CHECK dies with a fatal error if condition is not true.  It is *not*
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// controlled by NDEBUG, so the check will be executed regardless of
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compilation mode.  Therefore, it is safe to do things like:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    CHECK(fp->Write(x) == 4)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note we use write instead of printf/puts to avoid the risk we'll
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call malloc().
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK(condition)                                                \
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {                                                                  \
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(condition)) {                                                 \
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WRITE_TO_STDERR("Check failed: " #condition "\n",                 \
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      sizeof("Check failed: " #condition "\n")-1);      \
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcmalloc::Abort();                                                \
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }                                                                   \
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This takes a message to print.  The name is historical.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_CHECK(condition, message)                                          \
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {                                                                         \
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(condition)) {                                                        \
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WRITE_TO_STDERR("Check failed: " #condition ": " message "\n",           \
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      sizeof("Check failed: " #condition ": " message "\n")-1);\
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcmalloc::Abort();                                                       \
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }                                                                          \
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is like RAW_CHECK, but only in debug-mode
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { DEBUG_MODE = 0 };
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_DCHECK(condition, message)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { DEBUG_MODE = 1 };
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_DCHECK(condition, message)  RAW_CHECK(condition, message)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This prints errno as well.  Note we use write instead of printf/puts to
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoid the risk we'll call malloc().
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PCHECK(condition)                                               \
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {                                                                  \
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(condition)) {                                                 \
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const int err_no = errno;                                         \
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WRITE_TO_STDERR("Check failed: " #condition ": ",                 \
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      sizeof("Check failed: " #condition ": ")-1);      \
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no)));      \
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WRITE_TO_STDERR("\n", sizeof("\n")-1);                            \
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcmalloc::Abort();                                                \
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }                                                                   \
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro for binary operators; prints the two values on error
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't use this macro directly in your code, use CHECK_EQ et al below
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: These don't compile correctly if one of the arguments is a pointer
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the other is NULL. To work around this, simply static_cast NULL to the
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type of the desired pointer.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(jandrews): Also print the values in case of failure.  Requires some
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sort of type-sensitive ToString() function.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_OP(op, val1, val2)                                        \
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {                                                                  \
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!((val1) op (val2))) {                                          \
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcmalloc::Abort();                                                \
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }                                                                   \
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Synonyms for CHECK_* that are used in some unittests.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As are these variants.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_TRUE(cond)     CHECK(cond)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_FALSE(cond)    CHECK(!(cond))
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_STREQ(a, b)    CHECK(strcmp(a, b) == 0)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_TRUE(cond)     EXPECT_TRUE(cond)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_FALSE(cond)    EXPECT_FALSE(cond)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STREQ(a, b)    EXPECT_STREQ(a, b)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used for (libc) functions that return -1 and set errno
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_ERR(invocation)  PCHECK((invocation) != -1)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A few more checks that only happen in debug mode
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_EQ(val1, val2)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_NE(val1, val2)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LE(val1, val2)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LT(val1, val2)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GE(val1, val2)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GT(val1, val2)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_EQ(val1, val2)  CHECK_EQ(val1, val2)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_NE(val1, val2)  CHECK_NE(val1, val2)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LE(val1, val2)  CHECK_LE(val1, val2)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LT(val1, val2)  CHECK_LT(val1, val2)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GE(val1, val2)  CHECK_GE(val1, val2)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GT(val1, val2)  CHECK_GT(val1, val2)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ERROR
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ERROR      // may conflict with ERROR macro on windows
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: we add a newline to the end of the output if it's not there already
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LogPrintf(int severity, const char* pat, va_list ap) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We write directly to the stderr file descriptor and avoid FILE
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffering because that may invoke malloc()
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buf[1600];
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  perftools_vsnprintf(buf, sizeof(buf)-1, pat, ap);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(strlen(buf)+1 < sizeof(buf));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strcat(buf, "\n");
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(__ANDROID__) || defined(ANDROID)
212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  android_LogPriority priority = ANDROID_LOG_UNKNOWN;
213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  switch (severity) {
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case INFO: {
215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      priority = ANDROID_LOG_INFO;
216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case WARNING: {
219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      priority = ANDROID_LOG_WARN;
220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case ERROR: {
223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      priority = ANDROID_LOG_ERROR;
224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case FATAL: {
227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      priority = ANDROID_LOG_FATAL;
228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
230b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  __android_log_write(priority, "gperftools", buf);
232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else  // defined(__ANDROID__) || defined(ANDROID)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WRITE_TO_STDERR(buf, strlen(buf));
234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif  // defined(__ANDROID__) || defined(ANDROID)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((severity) == FATAL) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // LOG(FATAL) indicates a big problem, so don't run atexit() calls
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tcmalloc::Abort();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that since the order of global constructors is unspecified,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// global code that calls RAW_LOG may execute before FLAGS_verbose is set.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Such code will run with verbosity == 0 no matter what.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_PRINTF(severity, pat) do {          \
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (VLOG_IS_ON(severity)) {                   \
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_list ap;                                 \
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_start(ap, pat);                          \
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogPrintf(severity, pat, ap);               \
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_end(ap);                                 \
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                             \
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} while (0)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RAW_LOG is the main function; some synonyms are used in unittests.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void RAW_LOG(int lvl, const char* pat, ...)  { LOG_PRINTF(lvl, pat); }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LOG(int lvl, const char* pat, ...)      { LOG_PRINTF(lvl, pat); }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void VLOG(int lvl, const char* pat, ...)     { LOG_PRINTF(lvl, pat); }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LOG_IF(int lvl, bool cond, const char* pat, ...) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cond)  LOG_PRINTF(lvl, pat);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This isn't technically logging, but it's also IO and also is an
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// attempt to be "raw" -- that is, to not use any higher-level libc
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// routines that might allocate memory or (ideally) try to allocate
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// locks.  We use an opaque file handle (not necessarily an int)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to allow even more low-level stuff in the future.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Like other "raw" routines, these functions are best effort, and
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thus don't return error codes (except RawOpenForWriting()).
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NOMINMAX
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOMINMAX     // @#!$& windows
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef HANDLE RawFD;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int RawFD;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const RawFD kIllegalRawFD = -1;   // what open returns if it fails
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RawFD RawOpenForWriting(const char* filename);   // uses default permissions
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RawWrite(RawFD fd, const char* buf, size_t len);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RawClose(RawFD fd);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // _LOGGING_H_
289