1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef BASE_LOGGING_H 18 #define BASE_LOGGING_H 19 20 #include <functional> 21 #include <memory> 22 #include <ostream> 23 24 #include "base/macros.h" 25 26 namespace android { 27 namespace base { 28 29 enum LogSeverity { 30 VERBOSE, 31 DEBUG, 32 INFO, 33 WARNING, 34 ERROR, 35 FATAL, 36 }; 37 38 enum LogId { 39 DEFAULT, 40 MAIN, 41 SYSTEM, 42 }; 43 44 typedef std::function<void(LogId, LogSeverity, const char*, const char*, 45 unsigned int, const char*)> LogFunction; 46 47 extern void StderrLogger(LogId, LogSeverity, const char*, const char*, 48 unsigned int, const char*); 49 50 #ifdef __ANDROID__ 51 // We expose this even though it is the default because a user that wants to 52 // override the default log buffer will have to construct this themselves. 53 class LogdLogger { 54 public: 55 explicit LogdLogger(LogId default_log_id = android::base::MAIN); 56 57 void operator()(LogId, LogSeverity, const char* tag, const char* file, 58 unsigned int line, const char* message); 59 60 private: 61 LogId default_log_id_; 62 }; 63 #endif 64 65 // Configure logging based on ANDROID_LOG_TAGS environment variable. 66 // We need to parse a string that looks like 67 // 68 // *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i 69 // 70 // The tag (or '*' for the global level) comes first, followed by a colon and a 71 // letter indicating the minimum priority level we're expected to log. This can 72 // be used to reveal or conceal logs with specific tags. 73 extern void InitLogging(char* argv[], LogFunction&& logger); 74 75 // Configures logging using the default logger (logd for the device, stderr for 76 // the host). 77 extern void InitLogging(char* argv[]); 78 79 // Replace the current logger. 80 extern void SetLogger(LogFunction&& logger); 81 82 // Logs a message to logcat on Android otherwise to stderr. If the severity is 83 // FATAL it also causes an abort. For example: 84 // 85 // LOG(FATAL) << "We didn't expect to reach here"; 86 #define LOG(severity) \ 87 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ 88 ::android::base::severity, -1).stream() 89 90 // Logs a message to logcat with the specified log ID on Android otherwise to 91 // stderr. If the severity is FATAL it also causes an abort. 92 #define LOG_TO(dest, severity) \ 93 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::dest, \ 94 ::android::base::severity, -1).stream() 95 96 // A variant of LOG that also logs the current errno value. To be used when 97 // library calls fail. 98 #define PLOG(severity) \ 99 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ 100 ::android::base::severity, errno).stream() 101 102 // Behaves like PLOG, but logs to the specified log ID. 103 #define PLOG_TO(dest, severity) \ 104 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::dest, \ 105 ::android::base::severity, errno).stream() 106 107 // Marker that code is yet to be implemented. 108 #define UNIMPLEMENTED(level) \ 109 LOG(level) << __PRETTY_FUNCTION__ << " unimplemented " 110 111 // Check whether condition x holds and LOG(FATAL) if not. The value of the 112 // expression x is only evaluated once. Extra logging can be appended using << 113 // after. For example: 114 // 115 // CHECK(false == true) results in a log message of 116 // "Check failed: false == true". 117 #define CHECK(x) \ 118 if (UNLIKELY(!(x))) \ 119 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ 120 ::android::base::FATAL, -1).stream() \ 121 << "Check failed: " #x << " " 122 123 // Helper for CHECK_xx(x,y) macros. 124 #define CHECK_OP(LHS, RHS, OP) \ 125 for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS); \ 126 UNLIKELY(!(_values.lhs OP _values.rhs)); \ 127 /* empty */) \ 128 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ 129 ::android::base::FATAL, -1).stream() \ 130 << "Check failed: " << #LHS << " " << #OP << " " << #RHS \ 131 << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") " 132 133 // Check whether a condition holds between x and y, LOG(FATAL) if not. The value 134 // of the expressions x and y is evaluated once. Extra logging can be appended 135 // using << after. For example: 136 // 137 // CHECK_NE(0 == 1, false) results in 138 // "Check failed: false != false (0==1=false, false=false) ". 139 #define CHECK_EQ(x, y) CHECK_OP(x, y, == ) 140 #define CHECK_NE(x, y) CHECK_OP(x, y, != ) 141 #define CHECK_LE(x, y) CHECK_OP(x, y, <= ) 142 #define CHECK_LT(x, y) CHECK_OP(x, y, < ) 143 #define CHECK_GE(x, y) CHECK_OP(x, y, >= ) 144 #define CHECK_GT(x, y) CHECK_OP(x, y, > ) 145 146 // Helper for CHECK_STRxx(s1,s2) macros. 147 #define CHECK_STROP(s1, s2, sense) \ 148 if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \ 149 LOG(FATAL) << "Check failed: " \ 150 << "\"" << s1 << "\"" \ 151 << (sense ? " == " : " != ") << "\"" << s2 << "\"" 152 153 // Check for string (const char*) equality between s1 and s2, LOG(FATAL) if not. 154 #define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true) 155 #define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false) 156 157 // Perform the pthread function call(args), LOG(FATAL) on error. 158 #define CHECK_PTHREAD_CALL(call, args, what) \ 159 do { \ 160 int rc = call args; \ 161 if (rc != 0) { \ 162 errno = rc; \ 163 PLOG(FATAL) << #call << " failed for " << what; \ 164 } \ 165 } while (false) 166 167 // CHECK that can be used in a constexpr function. For example: 168 // 169 // constexpr int half(int n) { 170 // return 171 // DCHECK_CONSTEXPR(n >= 0, , 0) 172 // CHECK_CONSTEXPR((n & 1) == 0), 173 // << "Extra debugging output: n = " << n, 0) 174 // n / 2; 175 // } 176 #define CHECK_CONSTEXPR(x, out, dummy) \ 177 (UNLIKELY(!(x))) \ 178 ? (LOG(FATAL) << "Check failed: " << #x out, dummy) \ 179 : 180 181 // DCHECKs are debug variants of CHECKs only enabled in debug builds. Generally 182 // CHECK should be used unless profiling identifies a CHECK as being in 183 // performance critical code. 184 #if defined(NDEBUG) 185 static constexpr bool kEnableDChecks = false; 186 #else 187 static constexpr bool kEnableDChecks = true; 188 #endif 189 190 #define DCHECK(x) \ 191 if (::android::base::kEnableDChecks) CHECK(x) 192 #define DCHECK_EQ(x, y) \ 193 if (::android::base::kEnableDChecks) CHECK_EQ(x, y) 194 #define DCHECK_NE(x, y) \ 195 if (::android::base::kEnableDChecks) CHECK_NE(x, y) 196 #define DCHECK_LE(x, y) \ 197 if (::android::base::kEnableDChecks) CHECK_LE(x, y) 198 #define DCHECK_LT(x, y) \ 199 if (::android::base::kEnableDChecks) CHECK_LT(x, y) 200 #define DCHECK_GE(x, y) \ 201 if (::android::base::kEnableDChecks) CHECK_GE(x, y) 202 #define DCHECK_GT(x, y) \ 203 if (::android::base::kEnableDChecks) CHECK_GT(x, y) 204 #define DCHECK_STREQ(s1, s2) \ 205 if (::android::base::kEnableDChecks) CHECK_STREQ(s1, s2) 206 #define DCHECK_STRNE(s1, s2) \ 207 if (::android::base::kEnableDChecks) CHECK_STRNE(s1, s2) 208 #if defined(NDEBUG) 209 #define DCHECK_CONSTEXPR(x, out, dummy) 210 #else 211 #define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy) 212 #endif 213 214 // Temporary class created to evaluate the LHS and RHS, used with 215 // MakeEagerEvaluator to infer the types of LHS and RHS. 216 template <typename LHS, typename RHS> 217 struct EagerEvaluator { 218 EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) { 219 } 220 LHS lhs; 221 RHS rhs; 222 }; 223 224 // Helper function for CHECK_xx. 225 template <typename LHS, typename RHS> 226 static inline EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) { 227 return EagerEvaluator<LHS, RHS>(lhs, rhs); 228 } 229 230 // Explicitly instantiate EagerEvalue for pointers so that char*s aren't treated 231 // as strings. To compare strings use CHECK_STREQ and CHECK_STRNE. We rely on 232 // signed/unsigned warnings to protect you against combinations not explicitly 233 // listed below. 234 #define EAGER_PTR_EVALUATOR(T1, T2) \ 235 template <> \ 236 struct EagerEvaluator<T1, T2> { \ 237 EagerEvaluator(T1 l, T2 r) \ 238 : lhs(reinterpret_cast<const void*>(l)), \ 239 rhs(reinterpret_cast<const void*>(r)) { \ 240 } \ 241 const void* lhs; \ 242 const void* rhs; \ 243 } 244 EAGER_PTR_EVALUATOR(const char*, const char*); 245 EAGER_PTR_EVALUATOR(const char*, char*); 246 EAGER_PTR_EVALUATOR(char*, const char*); 247 EAGER_PTR_EVALUATOR(char*, char*); 248 EAGER_PTR_EVALUATOR(const unsigned char*, const unsigned char*); 249 EAGER_PTR_EVALUATOR(const unsigned char*, unsigned char*); 250 EAGER_PTR_EVALUATOR(unsigned char*, const unsigned char*); 251 EAGER_PTR_EVALUATOR(unsigned char*, unsigned char*); 252 EAGER_PTR_EVALUATOR(const signed char*, const signed char*); 253 EAGER_PTR_EVALUATOR(const signed char*, signed char*); 254 EAGER_PTR_EVALUATOR(signed char*, const signed char*); 255 EAGER_PTR_EVALUATOR(signed char*, signed char*); 256 257 // Data for the log message, not stored in LogMessage to avoid increasing the 258 // stack size. 259 class LogMessageData; 260 261 // A LogMessage is a temporarily scoped object used by LOG and the unlikely part 262 // of a CHECK. The destructor will abort if the severity is FATAL. 263 class LogMessage { 264 public: 265 LogMessage(const char* file, unsigned int line, LogId id, 266 LogSeverity severity, int error); 267 268 ~LogMessage(); 269 270 // Returns the stream associated with the message, the LogMessage performs 271 // output when it goes out of scope. 272 std::ostream& stream(); 273 274 // The routine that performs the actual logging. 275 static void LogLine(const char* file, unsigned int line, LogId id, 276 LogSeverity severity, const char* msg); 277 278 private: 279 const std::unique_ptr<LogMessageData> data_; 280 281 DISALLOW_COPY_AND_ASSIGN(LogMessage); 282 }; 283 284 // Allows to temporarily change the minimum severity level for logging. 285 class ScopedLogSeverity { 286 public: 287 explicit ScopedLogSeverity(LogSeverity level); 288 ~ScopedLogSeverity(); 289 290 private: 291 LogSeverity old_; 292 }; 293 294 } // namespace base 295 } // namespace android 296 297 #endif // BASE_LOGGING_H 298