logging.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/abort.h" 49#include "base/commandlineflags.h" 50 51// On some systems (like freebsd), we can't call write() at all in a 52// global constructor, perhaps because errno hasn't been set up. 53// (In windows, we can't call it because it might call malloc.) 54// Calling the write syscall is safer (it doesn't set errno), so we 55// prefer that. Note we don't care about errno for logging: we just 56// do logging on a best-effort basis. 57#if defined(_MSC_VER) 58#define WRITE_TO_STDERR(buf, len) WriteToStderr(buf, len); // in port.cc 59#elif defined(HAVE_SYS_SYSCALL_H) 60#include <sys/syscall.h> 61#define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len) 62#else 63#define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len) 64#endif 65 66// MSVC and mingw define their own, safe version of vnsprintf (the 67// windows one in broken) in port.cc. Everyone else can use the 68// version here. We had to give it a unique name for windows. 69#ifndef _WIN32 70# define perftools_vsnprintf vsnprintf 71#endif 72 73 74// We log all messages at this log-level and below. 75// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4 76DECLARE_int32(verbose); 77 78// CHECK dies with a fatal error if condition is not true. It is *not* 79// controlled by NDEBUG, so the check will be executed regardless of 80// compilation mode. Therefore, it is safe to do things like: 81// CHECK(fp->Write(x) == 4) 82// Note we use write instead of printf/puts to avoid the risk we'll 83// call malloc(). 84#define CHECK(condition) \ 85 do { \ 86 if (!(condition)) { \ 87 WRITE_TO_STDERR("Check failed: " #condition "\n", \ 88 sizeof("Check failed: " #condition "\n")-1); \ 89 tcmalloc::Abort(); \ 90 } \ 91 } while (0) 92 93// This takes a message to print. The name is historical. 94#define RAW_CHECK(condition, message) \ 95 do { \ 96 if (!(condition)) { \ 97 WRITE_TO_STDERR("Check failed: " #condition ": " message "\n", \ 98 sizeof("Check failed: " #condition ": " message "\n")-1);\ 99 tcmalloc::Abort(); \ 100 } \ 101 } while (0) 102 103// This is like RAW_CHECK, but only in debug-mode 104#ifdef NDEBUG 105enum { DEBUG_MODE = 0 }; 106#define RAW_DCHECK(condition, message) 107#else 108enum { DEBUG_MODE = 1 }; 109#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) 110#endif 111 112// This prints errno as well. Note we use write instead of printf/puts to 113// avoid the risk we'll call malloc(). 114#define PCHECK(condition) \ 115 do { \ 116 if (!(condition)) { \ 117 const int err_no = errno; \ 118 WRITE_TO_STDERR("Check failed: " #condition ": ", \ 119 sizeof("Check failed: " #condition ": ")-1); \ 120 WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no))); \ 121 WRITE_TO_STDERR("\n", sizeof("\n")-1); \ 122 tcmalloc::Abort(); \ 123 } \ 124 } while (0) 125 126// Helper macro for binary operators; prints the two values on error 127// Don't use this macro directly in your code, use CHECK_EQ et al below 128 129// WARNING: These don't compile correctly if one of the arguments is a pointer 130// and the other is NULL. To work around this, simply static_cast NULL to the 131// type of the desired pointer. 132 133// TODO(jandrews): Also print the values in case of failure. Requires some 134// sort of type-sensitive ToString() function. 135#define CHECK_OP(op, val1, val2) \ 136 do { \ 137 if (!((val1) op (val2))) { \ 138 fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \ 139 tcmalloc::Abort(); \ 140 } \ 141 } while (0) 142 143#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2) 144#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2) 145#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2) 146#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2) 147#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2) 148#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2) 149 150// Synonyms for CHECK_* that are used in some unittests. 151#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2) 152#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2) 153#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2) 154#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2) 155#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2) 156#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2) 157#define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2) 158#define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2) 159#define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2) 160#define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2) 161#define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2) 162#define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2) 163// As are these variants. 164#define EXPECT_TRUE(cond) CHECK(cond) 165#define EXPECT_FALSE(cond) CHECK(!(cond)) 166#define EXPECT_STREQ(a, b) CHECK(strcmp(a, b) == 0) 167#define ASSERT_TRUE(cond) EXPECT_TRUE(cond) 168#define ASSERT_FALSE(cond) EXPECT_FALSE(cond) 169#define ASSERT_STREQ(a, b) EXPECT_STREQ(a, b) 170 171// Used for (libc) functions that return -1 and set errno 172#define CHECK_ERR(invocation) PCHECK((invocation) != -1) 173 174// A few more checks that only happen in debug mode 175#ifdef NDEBUG 176#define DCHECK_EQ(val1, val2) 177#define DCHECK_NE(val1, val2) 178#define DCHECK_LE(val1, val2) 179#define DCHECK_LT(val1, val2) 180#define DCHECK_GE(val1, val2) 181#define DCHECK_GT(val1, val2) 182#else 183#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) 184#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) 185#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) 186#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) 187#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) 188#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) 189#endif 190 191 192#ifdef ERROR 193#undef ERROR // may conflict with ERROR macro on windows 194#endif 195enum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4}; 196 197// NOTE: we add a newline to the end of the output if it's not there already 198inline void LogPrintf(int severity, const char* pat, va_list ap) { 199 // We write directly to the stderr file descriptor and avoid FILE 200 // buffering because that may invoke malloc() 201 char buf[1600]; 202 perftools_vsnprintf(buf, sizeof(buf)-1, pat, ap); 203 if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') { 204 assert(strlen(buf)+1 < sizeof(buf)); 205 strcat(buf, "\n"); 206 } 207 WRITE_TO_STDERR(buf, strlen(buf)); 208 if ((severity) == FATAL) { 209 // LOG(FATAL) indicates a big problem, so don't run atexit() calls 210 tcmalloc::Abort(); 211 } 212} 213 214// Note that since the order of global constructors is unspecified, 215// global code that calls RAW_LOG may execute before FLAGS_verbose is set. 216// Such code will run with verbosity == 0 no matter what. 217#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity) 218 219// In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it. 220#define LOG_PRINTF(severity, pat) do { \ 221 if (VLOG_IS_ON(severity)) { \ 222 va_list ap; \ 223 va_start(ap, pat); \ 224 LogPrintf(severity, pat, ap); \ 225 va_end(ap); \ 226 } \ 227} while (0) 228 229// RAW_LOG is the main function; some synonyms are used in unittests. 230inline void RAW_LOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 231inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 232inline void LOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 233inline void VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 234inline void LOG_IF(int lvl, bool cond, const char* pat, ...) { 235 if (cond) LOG_PRINTF(lvl, pat); 236} 237 238// This isn't technically logging, but it's also IO and also is an 239// attempt to be "raw" -- that is, to not use any higher-level libc 240// routines that might allocate memory or (ideally) try to allocate 241// locks. We use an opaque file handle (not necessarily an int) 242// to allow even more low-level stuff in the future. 243// Like other "raw" routines, these functions are best effort, and 244// thus don't return error codes (except RawOpenForWriting()). 245#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) 246#ifndef NOMINMAX 247#define NOMINMAX // @#!$& windows 248#endif 249#include <windows.h> 250typedef HANDLE RawFD; 251const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE; 252#else 253typedef int RawFD; 254const RawFD kIllegalRawFD = -1; // what open returns if it fails 255#endif // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) 256 257RawFD RawOpenForWriting(const char* filename); // uses default permissions 258void RawWrite(RawFD fd, const char* buf, size_t len); 259void RawClose(RawFD fd); 260 261#endif // _LOGGING_H_ 262