Android-cuttlefish cvd tool
logging.h
Go to the documentation of this file.
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#pragma once
18
19#define __builtin_available(v1, v2) false
20
21//
22// Google-style C++ logging.
23//
24
25// This header provides a C++ stream interface to logging.
26//
27// To log:
28//
29// LOG(INFO) << "Some text; " << some_value;
30//
31// Replace `INFO` with any severity from `enum LogSeverity`.
32// Most devices filter out VERBOSE logs by default, run
33// `adb shell setprop log.tag.<TAG> V` to see them in adb logcat.
34//
35// To log the result of a failed function and include the string
36// representation of `errno` at the end:
37//
38// PLOG(ERROR) << "Write failed";
39//
40// The output will be something like `Write failed: I/O error`.
41// Remember this as 'P' as in perror(3).
42//
43// To output your own types, simply implement operator<< as normal.
44//
45// By default, output goes to logcat on Android and stderr on the host.
46// A process can use `SetLogger` to decide where all logging goes.
47// Implementations are provided for logcat, stderr, and dmesg.
48//
49// By default, the process' name is used as the log tag.
50// Code can choose a specific log tag by defining LOG_TAG
51// before including this header.
52
53// This header also provides assertions:
54//
55// CHECK(must_be_true);
56// CHECK_EQ(a, b) << z_is_interesting_too;
57
58// NOTE: For Windows, you must include logging.h after windows.h to allow the
59// following code to suppress the evil ERROR macro:
60#ifdef _WIN32
61// windows.h includes wingdi.h which defines an evil macro ERROR.
62#ifdef ERROR
63#undef ERROR
64#endif
65#endif
66
67#include <functional>
68#include <memory>
69#include <ostream>
70
72#include "android-base/macros.h"
73
74// Note: DO NOT USE DIRECTLY. Use LOG_TAG instead.
75#ifdef _LOG_TAG_INTERNAL
76#error "_LOG_TAG_INTERNAL must not be defined"
77#endif
78#ifdef LOG_TAG
79#define _LOG_TAG_INTERNAL LOG_TAG
80#else
81#define _LOG_TAG_INTERNAL nullptr
82#endif
83
84namespace android {
85namespace base {
86
93 FATAL_WITHOUT_ABORT, // For loggability tests, this is considered identical to FATAL.
95};
96
97enum LogId {
103};
104
105using LogFunction = std::function<void(LogId /*log_buffer_id*/,
106 LogSeverity /*severity*/,
107 const char* /*tag*/,
108 const char* /*file*/,
109 unsigned int /*line*/,
110 const char* /*message*/)>;
111using AbortFunction = std::function<void(const char* /*abort_message*/)>;
112
113// Loggers for use with InitLogging/SetLogger.
114
115// Log to the kernel log (dmesg).
116void KernelLogger(LogId log_buffer_id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message);
117// Log to stderr in the full logcat format (with pid/tid/time/tag details).
118void StderrLogger(LogId log_buffer_id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message);
119// Log just the message to stdout/stderr (without pid/tid/time/tag details).
120// The choice of stdout versus stderr is based on the severity.
121// Errors are also prefixed by the program name (as with err(3)/error(3)).
122// Useful for replacing printf(3)/perror(3)/err(3)/error(3) in command-line tools.
123void StdioLogger(LogId log_buffer_id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message);
124
125void DefaultAborter(const char* abort_message);
126
127void SetDefaultTag(const std::string& tag);
128
129// The LogdLogger sends chunks of up to ~4000 bytes at a time to logd. It does not prevent other
130// threads from writing to logd between sending each chunk, so other threads may interleave their
131// messages. If preventing interleaving is required, then a custom logger that takes a lock before
132// calling this logger should be provided.
134 public:
135 explicit LogdLogger(LogId default_log_id = android::base::MAIN);
136
137 void operator()(LogId, LogSeverity, const char* tag, const char* file,
138 unsigned int line, const char* message);
139
140 private:
142};
143
144// Configure logging based on ANDROID_LOG_TAGS environment variable.
145// We need to parse a string that looks like
146//
147// *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
148//
149// The tag (or '*' for the global level) comes first, followed by a colon and a
150// letter indicating the minimum priority level we're expected to log. This can
151// be used to reveal or conceal logs with specific tags.
152#ifdef __ANDROID__
153#define INIT_LOGGING_DEFAULT_LOGGER LogdLogger()
154#else
155#define INIT_LOGGING_DEFAULT_LOGGER StderrLogger
156#endif
157void InitLogging(char* argv[],
159 AbortFunction&& aborter = DefaultAborter);
160#undef INIT_LOGGING_DEFAULT_LOGGER
161
162// Replace the current logger and return the old one.
164
165// Replace the current aborter and return the old one.
167
168// A helper macro that produces an expression that accepts both a qualified name and an
169// unqualified name for a LogSeverity, and returns a LogSeverity value.
170// Note: DO NOT USE DIRECTLY. This is an implementation detail.
171#define SEVERITY_LAMBDA(severity) ([&]() { \
172 using ::android::base::VERBOSE; \
173 using ::android::base::DEBUG; \
174 using ::android::base::INFO; \
175 using ::android::base::WARNING; \
176 using ::android::base::ERROR; \
177 using ::android::base::FATAL_WITHOUT_ABORT; \
178 using ::android::base::FATAL; \
179 return (severity); }())
180
181#ifdef __clang_analyzer__
182// Clang's static analyzer does not see the conditional statement inside
183// LogMessage's destructor that will abort on FATAL severity.
184#define ABORT_AFTER_LOG_FATAL for (;; abort())
185
186struct LogAbortAfterFullExpr {
187 ~LogAbortAfterFullExpr() __attribute__((noreturn)) { abort(); }
188 explicit operator bool() const { return false; }
189};
190// Provides an expression that evaluates to the truthiness of `x`, automatically
191// aborting if `c` is true.
192#define ABORT_AFTER_LOG_EXPR_IF(c, x) (((c) && ::android::base::LogAbortAfterFullExpr()) || (x))
193// Note to the static analyzer that we always execute FATAL logs in practice.
194#define MUST_LOG_MESSAGE(severity) (SEVERITY_LAMBDA(severity) == ::android::base::FATAL)
195#else
196#define ABORT_AFTER_LOG_FATAL
197#define ABORT_AFTER_LOG_EXPR_IF(c, x) (x)
198#define MUST_LOG_MESSAGE(severity) false
199#endif
200#define ABORT_AFTER_LOG_FATAL_EXPR(x) ABORT_AFTER_LOG_EXPR_IF(true, x)
201
202// Defines whether the given severity will be logged or silently swallowed.
203#define WOULD_LOG(severity) \
204 (UNLIKELY(::android::base::ShouldLog(SEVERITY_LAMBDA(severity), _LOG_TAG_INTERNAL)) || \
205 MUST_LOG_MESSAGE(severity))
206
207// Get an ostream that can be used for logging at the given severity and to the default
208// destination.
209//
210// Notes:
211// 1) This will not check whether the severity is high enough. One should use WOULD_LOG to filter
212// usage manually.
213// 2) This does not save and restore errno.
214#define LOG_STREAM(severity) \
215 ::android::base::LogMessage(__FILE__, __LINE__, SEVERITY_LAMBDA(severity), _LOG_TAG_INTERNAL, \
216 -1) \
217 .stream()
218
219// Logs a message to logcat on Android otherwise to stderr. If the severity is
220// FATAL it also causes an abort. For example:
221//
222// LOG(FATAL) << "We didn't expect to reach here";
223#define LOG(severity) LOGGING_PREAMBLE(severity) && LOG_STREAM(severity)
224
225// Checks if we want to log something, and sets up appropriate RAII objects if
226// so.
227// Note: DO NOT USE DIRECTLY. This is an implementation detail.
228#define LOGGING_PREAMBLE(severity) \
229 (WOULD_LOG(severity) && \
230 ABORT_AFTER_LOG_EXPR_IF((SEVERITY_LAMBDA(severity)) == ::android::base::FATAL, true) && \
231 ::android::base::ErrnoRestorer())
232
233// A variant of LOG that also logs the current errno value. To be used when
234// library calls fail.
235#define PLOG(severity) \
236 LOGGING_PREAMBLE(severity) && \
237 ::android::base::LogMessage(__FILE__, __LINE__, SEVERITY_LAMBDA(severity), \
238 _LOG_TAG_INTERNAL, errno) \
239 .stream()
240
241// Marker that code is yet to be implemented.
242#define UNIMPLEMENTED(level) \
243 LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
244
245// Check whether condition x holds and LOG(FATAL) if not. The value of the
246// expression x is only evaluated once. Extra logging can be appended using <<
247// after. For example:
248//
249// CHECK(false == true) results in a log message of
250// "Check failed: false == true".
251#define CHECK(x) \
252 LIKELY((x)) || ABORT_AFTER_LOG_FATAL_EXPR(false) || \
253 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, _LOG_TAG_INTERNAL, \
254 -1) \
255 .stream() \
256 << "Check failed: " #x << " "
257
258// clang-format off
259// Helper for CHECK_xx(x,y) macros.
260#define CHECK_OP(LHS, RHS, OP) \
261 for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS); \
262 UNLIKELY(!(_values.lhs.v OP _values.rhs.v)); \
263 /* empty */) \
264 ABORT_AFTER_LOG_FATAL \
265 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, _LOG_TAG_INTERNAL, -1) \
266 .stream() \
267 << "Check failed: " << #LHS << " " << #OP << " " << #RHS << " (" #LHS "=" \
268 << ::android::base::LogNullGuard<decltype(_values.lhs.v)>::Guard(_values.lhs.v) \
269 << ", " #RHS "=" \
270 << ::android::base::LogNullGuard<decltype(_values.rhs.v)>::Guard(_values.rhs.v) \
271 << ") "
272// clang-format on
273
274// Check whether a condition holds between x and y, LOG(FATAL) if not. The value
275// of the expressions x and y is evaluated once. Extra logging can be appended
276// using << after. For example:
277//
278// CHECK_NE(0 == 1, false) results in
279// "Check failed: false != false (0==1=false, false=false) ".
280#define CHECK_EQ(x, y) CHECK_OP(x, y, == )
281#define CHECK_NE(x, y) CHECK_OP(x, y, != )
282#define CHECK_LE(x, y) CHECK_OP(x, y, <= )
283#define CHECK_LT(x, y) CHECK_OP(x, y, < )
284#define CHECK_GE(x, y) CHECK_OP(x, y, >= )
285#define CHECK_GT(x, y) CHECK_OP(x, y, > )
286
287// clang-format off
288// Helper for CHECK_STRxx(s1,s2) macros.
289#define CHECK_STROP(s1, s2, sense) \
290 while (UNLIKELY((strcmp(s1, s2) == 0) != (sense))) \
291 ABORT_AFTER_LOG_FATAL \
292 ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, \
293 _LOG_TAG_INTERNAL, -1) \
294 .stream() \
295 << "Check failed: " << "\"" << (s1) << "\"" \
296 << ((sense) ? " == " : " != ") << "\"" << (s2) << "\""
297// clang-format on
298
299// Check for string (const char*) equality between s1 and s2, LOG(FATAL) if not.
300#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
301#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
302
303// Perform the pthread function call(args), LOG(FATAL) on error.
304#define CHECK_PTHREAD_CALL(call, args, what) \
305 do { \
306 int rc = call args; \
307 if (rc != 0) { \
308 errno = rc; \
309 ABORT_AFTER_LOG_FATAL \
310 PLOG(FATAL) << #call << " failed for " << (what); \
311 } \
312 } while (false)
313
314// DCHECKs are debug variants of CHECKs only enabled in debug builds. Generally
315// CHECK should be used unless profiling identifies a CHECK as being in
316// performance critical code.
317#if defined(NDEBUG) && !defined(__clang_analyzer__)
318static constexpr bool kEnableDChecks = false;
319#else
320static constexpr bool kEnableDChecks = true;
321#endif
322
323#define DCHECK(x) \
324 if (::android::base::kEnableDChecks) CHECK(x)
325#define DCHECK_EQ(x, y) \
326 if (::android::base::kEnableDChecks) CHECK_EQ(x, y)
327#define DCHECK_NE(x, y) \
328 if (::android::base::kEnableDChecks) CHECK_NE(x, y)
329#define DCHECK_LE(x, y) \
330 if (::android::base::kEnableDChecks) CHECK_LE(x, y)
331#define DCHECK_LT(x, y) \
332 if (::android::base::kEnableDChecks) CHECK_LT(x, y)
333#define DCHECK_GE(x, y) \
334 if (::android::base::kEnableDChecks) CHECK_GE(x, y)
335#define DCHECK_GT(x, y) \
336 if (::android::base::kEnableDChecks) CHECK_GT(x, y)
337#define DCHECK_STREQ(s1, s2) \
338 if (::android::base::kEnableDChecks) CHECK_STREQ(s1, s2)
339#define DCHECK_STRNE(s1, s2) \
340 if (::android::base::kEnableDChecks) CHECK_STRNE(s1, s2)
341
342namespace log_detail {
343
344// Temporary storage for a single eagerly evaluated check expression operand.
345template <typename T> struct Storage {
346 template <typename U> explicit constexpr Storage(U&& u) : v(std::forward<U>(u)) {}
347 explicit Storage(const Storage& t) = delete;
348 explicit Storage(Storage&& t) = delete;
349 T v;
350};
351
352// Partial specialization for smart pointers to avoid copying.
353template <typename T> struct Storage<std::unique_ptr<T>> {
354 explicit constexpr Storage(const std::unique_ptr<T>& ptr) : v(ptr.get()) {}
355 const T* v;
356};
357template <typename T> struct Storage<std::shared_ptr<T>> {
358 explicit constexpr Storage(const std::shared_ptr<T>& ptr) : v(ptr.get()) {}
359 const T* v;
360};
361
362// Type trait that checks if a type is a (potentially const) char pointer.
363template <typename T> struct IsCharPointer {
364 using Pointee = std::remove_cv_t<std::remove_pointer_t<T>>;
365 static constexpr bool value = std::is_pointer_v<T> &&
366 (std::is_same_v<Pointee, char> || std::is_same_v<Pointee, signed char> ||
367 std::is_same_v<Pointee, unsigned char>);
368};
369
370// Counterpart to Storage that depends on both operands. This is used to prevent
371// char pointers being treated as strings in the log output - they might point
372// to buffers of unprintable binary data.
373template <typename LHS, typename RHS> struct StorageTypes {
375 using LHSType = std::conditional_t<voidptr, const void*, LHS>;
376 using RHSType = std::conditional_t<voidptr, const void*, RHS>;
377};
378
379// Temporary class created to evaluate the LHS and RHS, used with
380// MakeEagerEvaluator to infer the types of LHS and RHS.
381template <typename LHS, typename RHS>
383 template <typename A, typename B> constexpr EagerEvaluator(A&& l, B&& r)
384 : lhs(std::forward<A>(l)), rhs(std::forward<B>(r)) {}
387};
388
389} // namespace log_detail
390
391// Converts std::nullptr_t and null char pointers to the string "null"
392// when writing the failure message.
393template <typename T> struct LogNullGuard {
394 static const T& Guard(const T& v) { return v; }
395};
396template <> struct LogNullGuard<std::nullptr_t> {
397 static const char* Guard(const std::nullptr_t&) { return "(null)"; }
398};
399template <> struct LogNullGuard<char*> {
400 static const char* Guard(const char* v) { return v ? v : "(null)"; }
401};
402template <> struct LogNullGuard<const char*> {
403 static const char* Guard(const char* v) { return v ? v : "(null)"; }
404};
405
406// Helper function for CHECK_xx.
407template <typename LHS, typename RHS>
408constexpr auto MakeEagerEvaluator(LHS&& lhs, RHS&& rhs) {
409 return log_detail::EagerEvaluator<std::decay_t<LHS>, std::decay_t<RHS>>(
410 std::forward<LHS>(lhs), std::forward<RHS>(rhs));
411}
412
413// Data for the log message, not stored in LogMessage to avoid increasing the
414// stack size.
415class LogMessageData;
416
417// A LogMessage is a temporarily scoped object used by LOG and the unlikely part
418// of a CHECK. The destructor will abort if the severity is FATAL.
420 public:
421 // LogId has been deprecated, but this constructor must exist for prebuilts.
422 LogMessage(const char* file, unsigned int line, LogId, LogSeverity severity, const char* tag,
423 int error);
424 LogMessage(const char* file, unsigned int line, LogSeverity severity, const char* tag, int error);
425
426 ~LogMessage();
427
428 // Returns the stream associated with the message, the LogMessage performs
429 // output when it goes out of scope.
430 std::ostream& stream();
431
432 // The routine that performs the actual logging.
433 static void LogLine(const char* file, unsigned int line, LogSeverity severity, const char* tag,
434 const char* msg);
435
436 private:
437 const std::unique_ptr<LogMessageData> data_;
438
440};
441
442// Get the minimum severity level for logging.
444
445// Set the minimum severity level for logging, returning the old severity.
447
448// Return whether or not a log message with the associated tag should be logged.
449bool ShouldLog(LogSeverity severity, const char* tag);
450
451// Allows to temporarily change the minimum severity level for logging.
453 public:
454 explicit ScopedLogSeverity(LogSeverity level);
456
457 private:
459};
460
461} // namespace base
462} // namespace android
463
464namespace std { // NOLINT(cert-dcl58-cpp)
465
466// Emit a warning of ostream<< with std::string*. The intention was most likely to print *string.
467//
468// Note: for this to work, we need to have this in a namespace.
469// Note: using a pragma because "-Wgcc-compat" (included in "-Weverything") complains about
470// diagnose_if.
471// Note: to print the pointer, use "<< static_cast<const void*>(string_pointer)" instead.
472// Note: a not-recommended alternative is to let Clang ignore the warning by adding
473// -Wno-user-defined-warnings to CPPFLAGS.
474#pragma clang diagnostic push
475#pragma clang diagnostic ignored "-Wgcc-compat"
476#define OSTREAM_STRING_POINTER_USAGE_WARNING \
477 __attribute__((diagnose_if(true, "Unexpected logging of string pointer", "warning")))
479std::ostream& operator<<(std::ostream& stream, const std::string* string_pointer) {
480 return stream << static_cast<const void*>(string_pointer);
481}
482#pragma clang diagnostic pop
483
484} // namespace std
Definition: logging.h:419
std::ostream & stream()
Definition: logging.cpp:509
LogMessage(const char *file, unsigned int line, LogId, LogSeverity severity, const char *tag, int error)
Definition: logging.cpp:468
const std::unique_ptr< LogMessageData > data_
Definition: logging.h:437
~LogMessage()
Definition: logging.cpp:476
DISALLOW_COPY_AND_ASSIGN(LogMessage)
static void LogLine(const char *file, unsigned int line, LogSeverity severity, const char *tag, const char *msg)
Definition: logging.cpp:513
Definition: logging.h:133
LogdLogger(LogId default_log_id=android::base::MAIN)
Definition: logging.cpp:324
LogId default_log_id_
Definition: logging.h:141
void operator()(LogId, LogSeverity, const char *tag, const char *file, unsigned int line, const char *message)
Definition: logging.cpp:326
Definition: logging.h:452
LogSeverity old_
Definition: logging.h:458
~ScopedLogSeverity()
Definition: logging.cpp:569
ScopedLogSeverity(LogSeverity level)
Definition: logging.cpp:565
#define error(format, args...)
Definition: fec_private.h:201
#define OSTREAM_STRING_POINTER_USAGE_WARNING
Definition: logging.h:476
#define INIT_LOGGING_DEFAULT_LOGGER
Definition: logging.h:155
void KernelLogger(LogId log_buffer_id, LogSeverity severity, const char *tag, const char *file, unsigned int line, const char *message)
std::function< void(const char *)> AbortFunction
Definition: logging.h:111
constexpr auto MakeEagerEvaluator(LHS &&lhs, RHS &&rhs)
Definition: logging.h:408
static constexpr bool kEnableDChecks
Definition: logging.h:320
void StdioLogger(LogId log_buffer_id, LogSeverity severity, const char *tag, const char *file, unsigned int line, const char *message)
Definition: logging.cpp:290
AbortFunction SetAborter(AbortFunction &&aborter)
Definition: logging.cpp:409
std::function< void(LogId, LogSeverity, const char *, const char *, unsigned int, const char *)> LogFunction
Definition: logging.h:110
void SetDefaultTag(const std::string &tag)
Definition: logging.cpp:213
bool ShouldLog(LogSeverity severity, const char *tag)
Definition: logging.cpp:542
LogFunction SetLogger(LogFunction &&logger)
Definition: logging.cpp:393
LogSeverity SetMinimumLogSeverity(LogSeverity new_severity)
Definition: logging.cpp:554
LogSeverity GetMinimumLogSeverity()
Definition: logging.cpp:534
LogId
Definition: logging.h:97
@ CRASH
Definition: logging.h:102
@ SYSTEM
Definition: logging.h:100
@ RADIO
Definition: logging.h:101
@ DEFAULT
Definition: logging.h:98
@ MAIN
Definition: logging.h:99
void DefaultAborter(const char *abort_message)
Definition: logging.cpp:300
LogSeverity
Definition: logging.h:87
@ DEBUG
Definition: logging.h:89
@ WARNING
Definition: logging.h:91
@ FATAL_WITHOUT_ABORT
Definition: logging.h:93
@ INFO
Definition: logging.h:90
@ FATAL
Definition: logging.h:94
@ VERBOSE
Definition: logging.h:88
@ ERROR
Definition: logging.h:92
void InitLogging(char *argv[], LogFunction &&logger=INIT_LOGGING_DEFAULT_LOGGER, AbortFunction &&aborter=DefaultAborter)
Definition: logging.cpp:335
void StderrLogger(LogId log_buffer_id, LogSeverity severity, const char *tag, const char *file, unsigned int line, const char *message)
Definition: logging.cpp:280
Size< 0 > B
Definition: storage_literals.h:36
Definition: map_ptr.h:34
class incremental::File __attribute__
Definition: logging.h:464
OSTREAM_STRING_POINTER_USAGE_WARNING std::ostream & operator<<(std::ostream &stream, const std::string *string_pointer)
Definition: logging.h:479
static const char * Guard(const char *v)
Definition: logging.h:400
static const char * Guard(const char *v)
Definition: logging.h:403
static const char * Guard(const std::nullptr_t &)
Definition: logging.h:397
Definition: logging.h:393
static const T & Guard(const T &v)
Definition: logging.h:394
const Storage< typename StorageTypes< LHS, RHS >::RHSType > rhs
Definition: logging.h:386
constexpr EagerEvaluator(A &&l, B &&r)
Definition: logging.h:383
const Storage< typename StorageTypes< LHS, RHS >::LHSType > lhs
Definition: logging.h:385
static constexpr bool value
Definition: logging.h:365
std::remove_cv_t< std::remove_pointer_t< T > > Pointee
Definition: logging.h:364
std::conditional_t< voidptr, const void *, RHS > RHSType
Definition: logging.h:376
static constexpr bool voidptr
Definition: logging.h:374
std::conditional_t< voidptr, const void *, LHS > LHSType
Definition: logging.h:375
constexpr Storage(const std::shared_ptr< T > &ptr)
Definition: logging.h:358
constexpr Storage(const std::unique_ptr< T > &ptr)
Definition: logging.h:354
Definition: logging.h:345
T v
Definition: logging.h:349
Storage(const Storage &t)=delete
constexpr Storage(U &&u)
Definition: logging.h:346