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