blob: caeb946ff0b7b4279775b3aa5a6738a0e97b0ff6 [file] [log] [blame]
Elliott Hughes42ee1422011-09-06 12:33:32 -07001/*
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 */
Carl Shapiro6c21dc12011-06-20 15:20:52 -070016
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_BASE_LOGGING_H_
18#define ART_RUNTIME_BASE_LOGGING_H_
Carl Shapiro6c21dc12011-06-20 15:20:52 -070019
Elliott Hugheseb4f6142011-07-15 17:43:51 -070020#include <cerrno>
21#include <cstring>
Carl Shapiro6c21dc12011-06-20 15:20:52 -070022#include <iostream> // NOLINT
Ian Rogers700a4022014-05-19 16:49:03 -070023#include <memory>
Elliott Hugheseb4f6142011-07-15 17:43:51 -070024#include <sstream>
Brian Carlstromaf1b8922012-11-27 15:19:57 -080025#include <signal.h>
Mingyao Yang42d65c52014-04-18 16:49:39 -070026#include <vector>
Ian Rogers700a4022014-05-19 16:49:03 -070027
Elliott Hughes76160052012-12-12 16:31:20 -080028#include "base/macros.h"
Elliott Hugheseb4f6142011-07-15 17:43:51 -070029#include "log_severity.h"
Carl Shapiro6c21dc12011-06-20 15:20:52 -070030
31#define CHECK(x) \
Ian Rogerscaab8c42011-10-12 12:11:18 -070032 if (UNLIKELY(!(x))) \
Elliott Hughesf5a7a472011-10-07 14:31:02 -070033 ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
Elliott Hughes710a0cb2011-08-16 14:32:37 -070034 << "Check failed: " #x << " "
Elliott Hugheseb4f6142011-07-15 17:43:51 -070035
Elliott Hughes1f359b02011-07-17 14:27:17 -070036#define CHECK_OP(LHS, RHS, OP) \
Mathieu Chartier9b3c3cd2013-08-12 17:41:54 -070037 for (auto _values = ::art::MakeEagerEvaluator(LHS, RHS); \
Elliott Hughes362f9bc2011-10-17 18:56:41 -070038 UNLIKELY(!(_values.lhs OP _values.rhs)); /* empty */) \
Elliott Hughesf5a7a472011-10-07 14:31:02 -070039 ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
40 << "Check failed: " << #LHS << " " << #OP << " " << #RHS \
41 << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") "
Elliott Hughes1f359b02011-07-17 14:27:17 -070042
43#define CHECK_EQ(x, y) CHECK_OP(x, y, ==)
44#define CHECK_NE(x, y) CHECK_OP(x, y, !=)
45#define CHECK_LE(x, y) CHECK_OP(x, y, <=)
46#define CHECK_LT(x, y) CHECK_OP(x, y, <)
47#define CHECK_GE(x, y) CHECK_OP(x, y, >=)
48#define CHECK_GT(x, y) CHECK_OP(x, y, >)
Elliott Hugheseb4f6142011-07-15 17:43:51 -070049
50#define CHECK_STROP(s1, s2, sense) \
Ian Rogerscaab8c42011-10-12 12:11:18 -070051 if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \
Elliott Hughesf5a7a472011-10-07 14:31:02 -070052 LOG(FATAL) << "Check failed: " \
53 << "\"" << s1 << "\"" \
54 << (sense ? " == " : " != ") \
55 << "\"" << s2 << "\""
Carl Shapiro6c21dc12011-06-20 15:20:52 -070056
Elliott Hughes1f359b02011-07-17 14:27:17 -070057#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
58#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
59
Elliott Hughes8d768a92011-09-14 16:35:25 -070060#define CHECK_PTHREAD_CALL(call, args, what) \
61 do { \
62 int rc = call args; \
63 if (rc != 0) { \
64 errno = rc; \
65 PLOG(FATAL) << # call << " failed for " << what; \
66 } \
67 } while (false)
68
Vladimir Marko83642482014-06-11 12:12:07 +010069// CHECK that can be used in a constexpr function. For example,
70// constexpr int half(int n) {
71// return
72// DCHECK_CONSTEXPR(n >= 0, , 0)
73// CHECK_CONSTEXPR((n & 1) == 0), << "Extra debugging output: n = " << n, 0)
74// n / 2;
75// }
76#define CHECK_CONSTEXPR(x, out, dummy) \
77 (UNLIKELY(!(x))) ? (LOG(FATAL) << "Check failed: " << #x out, dummy) :
78
Carl Shapiro6c21dc12011-06-20 15:20:52 -070079#ifndef NDEBUG
80
81#define DCHECK(x) CHECK(x)
82#define DCHECK_EQ(x, y) CHECK_EQ(x, y)
83#define DCHECK_NE(x, y) CHECK_NE(x, y)
84#define DCHECK_LE(x, y) CHECK_LE(x, y)
85#define DCHECK_LT(x, y) CHECK_LT(x, y)
86#define DCHECK_GE(x, y) CHECK_GE(x, y)
87#define DCHECK_GT(x, y) CHECK_GT(x, y)
Elliott Hugheseb4f6142011-07-15 17:43:51 -070088#define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2)
89#define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2)
Vladimir Marko83642482014-06-11 12:12:07 +010090#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)
Carl Shapiro6c21dc12011-06-20 15:20:52 -070091
92#else // NDEBUG
93
94#define DCHECK(condition) \
95 while (false) \
96 CHECK(condition)
97
98#define DCHECK_EQ(val1, val2) \
99 while (false) \
100 CHECK_EQ(val1, val2)
101
102#define DCHECK_NE(val1, val2) \
103 while (false) \
104 CHECK_NE(val1, val2)
105
106#define DCHECK_LE(val1, val2) \
107 while (false) \
108 CHECK_LE(val1, val2)
109
110#define DCHECK_LT(val1, val2) \
111 while (false) \
112 CHECK_LT(val1, val2)
113
114#define DCHECK_GE(val1, val2) \
115 while (false) \
116 CHECK_GE(val1, val2)
117
118#define DCHECK_GT(val1, val2) \
119 while (false) \
120 CHECK_GT(val1, val2)
121
122#define DCHECK_STREQ(str1, str2) \
123 while (false) \
124 CHECK_STREQ(str1, str2)
125
Elliott Hugheseb4f6142011-07-15 17:43:51 -0700126#define DCHECK_STRNE(str1, str2) \
127 while (false) \
128 CHECK_STRNE(str1, str2)
129
Vladimir Marko83642482014-06-11 12:12:07 +0100130#define DCHECK_CONSTEXPR(x, out, dummy) \
131 (false && (x)) ? (dummy) :
132
Carl Shapiro6c21dc12011-06-20 15:20:52 -0700133#endif
134
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700135#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
136#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()
Elliott Hugheseb4f6142011-07-15 17:43:51 -0700137
Carl Shapiro6c21dc12011-06-20 15:20:52 -0700138#define LG LOG(INFO)
139
Elliott Hughes8d768a92011-09-14 16:35:25 -0700140#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
Elliott Hughes53b61312011-08-12 18:28:20 -0700141
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800142#define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
143#define VLOG(module) if (VLOG_IS_ON(module)) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
Anwar Ghuloum75a43f12013-08-13 17:22:14 -0700144#define VLOG_STREAM(module) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800145
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700146//
147// Implementation details beyond this point.
148//
149
150namespace art {
151
152template <typename LHS, typename RHS>
153struct EagerEvaluator {
154 EagerEvaluator(LHS lhs, RHS rhs) : lhs(lhs), rhs(rhs) { }
155 LHS lhs;
156 RHS rhs;
157};
158
Elliott Hughesaa6a5882012-01-13 19:39:16 -0800159// We want char*s to be treated as pointers, not strings. If you want them treated like strings,
160// you'd need to use CHECK_STREQ and CHECK_STRNE anyway to compare the characters rather than their
161// addresses. We could express this more succinctly with std::remove_const, but this is quick and
162// easy to understand, and works before we have C++0x. We rely on signed/unsigned warnings to
163// protect you against combinations not explicitly listed below.
164#define EAGER_PTR_EVALUATOR(T1, T2) \
165 template <> struct EagerEvaluator<T1, T2> { \
166 EagerEvaluator(T1 lhs, T2 rhs) \
167 : lhs(reinterpret_cast<const void*>(lhs)), \
168 rhs(reinterpret_cast<const void*>(rhs)) { } \
169 const void* lhs; \
170 const void* rhs; \
171 }
172EAGER_PTR_EVALUATOR(const char*, const char*);
173EAGER_PTR_EVALUATOR(const char*, char*);
174EAGER_PTR_EVALUATOR(char*, const char*);
175EAGER_PTR_EVALUATOR(char*, char*);
176EAGER_PTR_EVALUATOR(const unsigned char*, const unsigned char*);
177EAGER_PTR_EVALUATOR(const unsigned char*, unsigned char*);
178EAGER_PTR_EVALUATOR(unsigned char*, const unsigned char*);
179EAGER_PTR_EVALUATOR(unsigned char*, unsigned char*);
180EAGER_PTR_EVALUATOR(const signed char*, const signed char*);
181EAGER_PTR_EVALUATOR(const signed char*, signed char*);
182EAGER_PTR_EVALUATOR(signed char*, const signed char*);
183EAGER_PTR_EVALUATOR(signed char*, signed char*);
184
Mathieu Chartier9b3c3cd2013-08-12 17:41:54 -0700185template <typename LHS, typename RHS>
186EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {
187 return EagerEvaluator<LHS, RHS>(lhs, rhs);
188}
189
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700190// This indirection greatly reduces the stack impact of having
191// lots of checks/logging in a function.
192struct LogMessageData {
193 public:
Brian Carlstromaf1b8922012-11-27 15:19:57 -0800194 LogMessageData(const char* file, int line, LogSeverity severity, int error);
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700195 std::ostringstream buffer;
Ian Rogersc4ee12e2013-05-16 11:19:53 -0700196 const char* const file;
197 const int line_number;
198 const LogSeverity severity;
199 const int error;
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700200
201 private:
202 DISALLOW_COPY_AND_ASSIGN(LogMessageData);
203};
204
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700205class LogMessage {
206 public:
Brian Carlstromaf1b8922012-11-27 15:19:57 -0800207 LogMessage(const char* file, int line, LogSeverity severity, int error)
208 : data_(new LogMessageData(file, line, severity, error)) {
209 }
Sebastien Hertz74c07042013-05-17 14:04:12 +0200210
Ian Rogers719d1a32014-03-06 12:13:39 -0800211 ~LogMessage(); // TODO: enable LOCKS_EXCLUDED(Locks::logging_lock_).
Sebastien Hertz74c07042013-05-17 14:04:12 +0200212
213 std::ostream& stream() {
214 return data_->buffer;
215 }
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700216
217 private:
Brian Carlstromaf1b8922012-11-27 15:19:57 -0800218 static void LogLine(const LogMessageData& data, const char*);
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700219
Ian Rogers700a4022014-05-19 16:49:03 -0700220 const std::unique_ptr<LogMessageData> data_;
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700221
Brian Carlstromaf1b8922012-11-27 15:19:57 -0800222 friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context);
Ian Rogersc4ee12e2013-05-16 11:19:53 -0700223 friend class Mutex;
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700224 DISALLOW_COPY_AND_ASSIGN(LogMessage);
225};
226
Elliott Hughese0918552011-10-28 17:18:29 -0700227// A convenience to allow any class with a "Dump(std::ostream& os)" member function
228// but without an operator<< to be used as if it had an operator<<. Use like this:
229//
230// os << Dumpable<MyType>(my_type_instance);
231//
232template<typename T>
233class Dumpable {
234 public:
235 explicit Dumpable(T& value) : value_(value) {
236 }
237
238 void Dump(std::ostream& os) const {
239 value_.Dump(os);
240 }
241
242 private:
243 T& value_;
Shih-wei Liao24782c62012-01-08 12:46:11 -0800244
Elliott Hughese0918552011-10-28 17:18:29 -0700245 DISALLOW_COPY_AND_ASSIGN(Dumpable);
246};
247
248template<typename T>
249std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
250 rhs.Dump(os);
251 return os;
252}
253
Mathieu Chartierafe49982014-03-27 10:55:04 -0700254template<typename T>
255class ConstDumpable {
256 public:
257 explicit ConstDumpable(const T& value) : value_(value) {
258 }
259
260 void Dump(std::ostream& os) const {
261 value_.Dump(os);
262 }
263
264 private:
265 const T& value_;
266
267 DISALLOW_COPY_AND_ASSIGN(ConstDumpable);
268};
269
270template<typename T>
271std::ostream& operator<<(std::ostream& os, const ConstDumpable<T>& rhs) {
272 rhs.Dump(os);
273 return os;
274}
275
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700276// Helps you use operator<< in a const char*-like context such as our various 'F' methods with
277// format strings.
278template<typename T>
279class ToStr {
280 public:
Elliott Hughes74847412012-06-20 18:10:21 -0700281 explicit ToStr(const T& value) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700282 std::ostringstream os;
283 os << value;
284 s_ = os.str();
285 }
286
287 const char* c_str() const {
288 return s_.c_str();
289 }
290
291 const std::string& str() const {
292 return s_;
293 }
294
295 private:
296 std::string s_;
297 DISALLOW_COPY_AND_ASSIGN(ToStr);
298};
299
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800300// The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
301// and the "-verbose:" command line argument.
302struct LogVerbosity {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700303 bool class_linker; // Enabled with "-verbose:class".
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800304 bool compiler;
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800305 bool gc;
Brian Carlstrom4d466a82014-05-08 19:05:29 -0700306 bool heap;
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800307 bool jdwp;
308 bool jni;
309 bool monitor;
Brian Carlstrom4d466a82014-05-08 19:05:29 -0700310 bool profiler;
311 bool signals;
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800312 bool startup;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700313 bool third_party_jni; // Enabled with "-verbose:third-party-jni".
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800314 bool threads;
Brian Carlstrom4d466a82014-05-08 19:05:29 -0700315 bool verifier;
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800316};
317
318extern LogVerbosity gLogVerbosity;
Brian Carlstrom81b88712012-11-05 19:21:30 -0800319
Mingyao Yang42d65c52014-04-18 16:49:39 -0700320extern std::vector<std::string> gVerboseMethods;
321
Brian Carlstrom81b88712012-11-05 19:21:30 -0800322// Used on fatal exit. Prevents recursive aborts. Allows us to disable
323// some error checking to ensure fatal shutdown makes forward progress.
Ian Rogersf08e4732013-04-09 09:45:49 -0700324extern unsigned int gAborting;
Brian Carlstrom81b88712012-11-05 19:21:30 -0800325
Elliott Hughes0d39c122012-06-06 16:41:17 -0700326extern void InitLogging(char* argv[]);
327
328extern const char* GetCmdLine();
329extern const char* ProgramInvocationName();
330extern const char* ProgramInvocationShortName();
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800331
Elliott Hughes3ea7e992011-10-11 18:48:16 -0700332} // namespace art
333
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700334#endif // ART_RUNTIME_BASE_LOGGING_H_