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