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 80 DECLARE_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 109 enum { DEBUG_MODE = 0 }; 110 #define RAW_DCHECK(condition, message) 111 #else 112 enum { 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 199 enum 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 202 inline 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. 261 inline void RAW_LOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 262 inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 263 inline void LOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 264 inline void VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); } 265 inline 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> 281 typedef HANDLE RawFD; 282 const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE; 283 #else 284 typedef int RawFD; 285 const RawFD kIllegalRawFD = -1; // what open returns if it fails 286 #endif // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) 287 288 RawFD RawOpenForWriting(const char* filename); // uses default permissions 289 void RawWrite(RawFD fd, const char* buf, size_t len); 290 void RawClose(RawFD fd); 291 292 #endif // _LOGGING_H_ 293