1 /* 2 * Copyright (C) 2011 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 ART_RUNTIME_BASE_LOGGING_H_ 18 #define ART_RUNTIME_BASE_LOGGING_H_ 19 20 #include <cerrno> 21 #include <cstring> 22 #include <iostream> // NOLINT 23 #include <sstream> 24 #include <signal.h> 25 #include "base/macros.h" 26 #include "log_severity.h" 27 #include "UniquePtr.h" 28 29 #define CHECK(x) \ 30 if (UNLIKELY(!(x))) \ 31 ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \ 32 << "Check failed: " #x << " " 33 34 #define CHECK_OP(LHS, RHS, OP) \ 35 for (auto _values = ::art::MakeEagerEvaluator(LHS, RHS); \ 36 UNLIKELY(!(_values.lhs OP _values.rhs)); /* empty */) \ 37 ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \ 38 << "Check failed: " << #LHS << " " << #OP << " " << #RHS \ 39 << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") " 40 41 #define CHECK_EQ(x, y) CHECK_OP(x, y, ==) 42 #define CHECK_NE(x, y) CHECK_OP(x, y, !=) 43 #define CHECK_LE(x, y) CHECK_OP(x, y, <=) 44 #define CHECK_LT(x, y) CHECK_OP(x, y, <) 45 #define CHECK_GE(x, y) CHECK_OP(x, y, >=) 46 #define CHECK_GT(x, y) CHECK_OP(x, y, >) 47 48 #define CHECK_STROP(s1, s2, sense) \ 49 if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \ 50 LOG(FATAL) << "Check failed: " \ 51 << "\"" << s1 << "\"" \ 52 << (sense ? " == " : " != ") \ 53 << "\"" << s2 << "\"" 54 55 #define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true) 56 #define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false) 57 58 #define CHECK_PTHREAD_CALL(call, args, what) \ 59 do { \ 60 int rc = call args; \ 61 if (rc != 0) { \ 62 errno = rc; \ 63 PLOG(FATAL) << # call << " failed for " << what; \ 64 } \ 65 } while (false) 66 67 #ifndef NDEBUG 68 69 #define DCHECK(x) CHECK(x) 70 #define DCHECK_EQ(x, y) CHECK_EQ(x, y) 71 #define DCHECK_NE(x, y) CHECK_NE(x, y) 72 #define DCHECK_LE(x, y) CHECK_LE(x, y) 73 #define DCHECK_LT(x, y) CHECK_LT(x, y) 74 #define DCHECK_GE(x, y) CHECK_GE(x, y) 75 #define DCHECK_GT(x, y) CHECK_GT(x, y) 76 #define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2) 77 #define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2) 78 79 #else // NDEBUG 80 81 #define DCHECK(condition) \ 82 while (false) \ 83 CHECK(condition) 84 85 #define DCHECK_EQ(val1, val2) \ 86 while (false) \ 87 CHECK_EQ(val1, val2) 88 89 #define DCHECK_NE(val1, val2) \ 90 while (false) \ 91 CHECK_NE(val1, val2) 92 93 #define DCHECK_LE(val1, val2) \ 94 while (false) \ 95 CHECK_LE(val1, val2) 96 97 #define DCHECK_LT(val1, val2) \ 98 while (false) \ 99 CHECK_LT(val1, val2) 100 101 #define DCHECK_GE(val1, val2) \ 102 while (false) \ 103 CHECK_GE(val1, val2) 104 105 #define DCHECK_GT(val1, val2) \ 106 while (false) \ 107 CHECK_GT(val1, val2) 108 109 #define DCHECK_STREQ(str1, str2) \ 110 while (false) \ 111 CHECK_STREQ(str1, str2) 112 113 #define DCHECK_STRNE(str1, str2) \ 114 while (false) \ 115 CHECK_STRNE(str1, str2) 116 117 #endif 118 119 #define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream() 120 #define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream() 121 122 #define LG LOG(INFO) 123 124 #define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented " 125 126 #define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module) 127 #define VLOG(module) if (VLOG_IS_ON(module)) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream() 128 #define VLOG_STREAM(module) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream() 129 130 // 131 // Implementation details beyond this point. 132 // 133 134 namespace art { 135 136 template <typename LHS, typename RHS> 137 struct EagerEvaluator { 138 EagerEvaluator(LHS lhs, RHS rhs) : lhs(lhs), rhs(rhs) { } 139 LHS lhs; 140 RHS rhs; 141 }; 142 143 // We want char*s to be treated as pointers, not strings. If you want them treated like strings, 144 // you'd need to use CHECK_STREQ and CHECK_STRNE anyway to compare the characters rather than their 145 // addresses. We could express this more succinctly with std::remove_const, but this is quick and 146 // easy to understand, and works before we have C++0x. We rely on signed/unsigned warnings to 147 // protect you against combinations not explicitly listed below. 148 #define EAGER_PTR_EVALUATOR(T1, T2) \ 149 template <> struct EagerEvaluator<T1, T2> { \ 150 EagerEvaluator(T1 lhs, T2 rhs) \ 151 : lhs(reinterpret_cast<const void*>(lhs)), \ 152 rhs(reinterpret_cast<const void*>(rhs)) { } \ 153 const void* lhs; \ 154 const void* rhs; \ 155 } 156 EAGER_PTR_EVALUATOR(const char*, const char*); 157 EAGER_PTR_EVALUATOR(const char*, char*); 158 EAGER_PTR_EVALUATOR(char*, const char*); 159 EAGER_PTR_EVALUATOR(char*, char*); 160 EAGER_PTR_EVALUATOR(const unsigned char*, const unsigned char*); 161 EAGER_PTR_EVALUATOR(const unsigned char*, unsigned char*); 162 EAGER_PTR_EVALUATOR(unsigned char*, const unsigned char*); 163 EAGER_PTR_EVALUATOR(unsigned char*, unsigned char*); 164 EAGER_PTR_EVALUATOR(const signed char*, const signed char*); 165 EAGER_PTR_EVALUATOR(const signed char*, signed char*); 166 EAGER_PTR_EVALUATOR(signed char*, const signed char*); 167 EAGER_PTR_EVALUATOR(signed char*, signed char*); 168 169 template <typename LHS, typename RHS> 170 EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) { 171 return EagerEvaluator<LHS, RHS>(lhs, rhs); 172 } 173 174 // This indirection greatly reduces the stack impact of having 175 // lots of checks/logging in a function. 176 struct LogMessageData { 177 public: 178 LogMessageData(const char* file, int line, LogSeverity severity, int error); 179 std::ostringstream buffer; 180 const char* const file; 181 const int line_number; 182 const LogSeverity severity; 183 const int error; 184 185 private: 186 DISALLOW_COPY_AND_ASSIGN(LogMessageData); 187 }; 188 189 class LogMessage { 190 public: 191 LogMessage(const char* file, int line, LogSeverity severity, int error) 192 : data_(new LogMessageData(file, line, severity, error)) { 193 } 194 195 ~LogMessage() LOCKS_EXCLUDED(Locks::logging_lock_); 196 197 std::ostream& stream() { 198 return data_->buffer; 199 } 200 201 private: 202 static void LogLine(const LogMessageData& data, const char*); 203 204 const UniquePtr<LogMessageData> data_; 205 206 friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context); 207 friend class Mutex; 208 DISALLOW_COPY_AND_ASSIGN(LogMessage); 209 }; 210 211 // Prints a hex dump in this format: 212 // 213 // 01234560: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef 214 // 01234568: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef 215 class HexDump { 216 public: 217 HexDump(const void* address, size_t byte_count, bool show_actual_addresses = false); 218 void Dump(std::ostream& os) const; 219 220 private: 221 const void* address_; 222 size_t byte_count_; 223 bool show_actual_addresses_; 224 225 DISALLOW_COPY_AND_ASSIGN(HexDump); 226 }; 227 std::ostream& operator<<(std::ostream& os, const HexDump& rhs); 228 229 // A convenience to allow any class with a "Dump(std::ostream& os)" member function 230 // but without an operator<< to be used as if it had an operator<<. Use like this: 231 // 232 // os << Dumpable<MyType>(my_type_instance); 233 // 234 template<typename T> 235 class Dumpable { 236 public: 237 explicit Dumpable(T& value) : value_(value) { 238 } 239 240 void Dump(std::ostream& os) const { 241 value_.Dump(os); 242 } 243 244 private: 245 T& value_; 246 247 DISALLOW_COPY_AND_ASSIGN(Dumpable); 248 }; 249 250 template<typename T> 251 std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) { 252 rhs.Dump(os); 253 return os; 254 } 255 256 template<typename T> 257 class MutatorLockedDumpable { 258 public: 259 explicit MutatorLockedDumpable(T& value) 260 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : value_(value) { 261 } 262 263 void Dump(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 264 value_.Dump(os); 265 } 266 267 private: 268 T& value_; 269 270 DISALLOW_COPY_AND_ASSIGN(MutatorLockedDumpable); 271 }; 272 273 template<typename T> 274 std::ostream& operator<<(std::ostream& os, const MutatorLockedDumpable<T>& rhs) 275 // TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) however annotalysis 276 // currently fails for this. 277 NO_THREAD_SAFETY_ANALYSIS { 278 rhs.Dump(os); 279 return os; 280 } 281 282 // Helps you use operator<< in a const char*-like context such as our various 'F' methods with 283 // format strings. 284 template<typename T> 285 class ToStr { 286 public: 287 explicit ToStr(const T& value) { 288 std::ostringstream os; 289 os << value; 290 s_ = os.str(); 291 } 292 293 const char* c_str() const { 294 return s_.c_str(); 295 } 296 297 const std::string& str() const { 298 return s_; 299 } 300 301 private: 302 std::string s_; 303 DISALLOW_COPY_AND_ASSIGN(ToStr); 304 }; 305 306 // The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code, 307 // and the "-verbose:" command line argument. 308 struct LogVerbosity { 309 bool class_linker; // Enabled with "-verbose:class". 310 bool verifier; 311 bool compiler; 312 bool heap; 313 bool gc; 314 bool jdwp; 315 bool jni; 316 bool monitor; 317 bool startup; 318 bool third_party_jni; // Enabled with "-verbose:third-party-jni". 319 bool threads; 320 }; 321 322 extern LogVerbosity gLogVerbosity; 323 324 // Used on fatal exit. Prevents recursive aborts. Allows us to disable 325 // some error checking to ensure fatal shutdown makes forward progress. 326 extern unsigned int gAborting; 327 328 extern void InitLogging(char* argv[]); 329 330 extern const char* GetCmdLine(); 331 extern const char* ProgramInvocationName(); 332 extern const char* ProgramInvocationShortName(); 333 334 } // namespace art 335 336 #endif // ART_RUNTIME_BASE_LOGGING_H_ 337