• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 INCLUDE_PERFETTO_BASE_LOGGING_H_
18 #define INCLUDE_PERFETTO_BASE_LOGGING_H_
19 
20 #include <errno.h>
21 #include <string.h>  // For strerror.
22 
23 #include "perfetto/base/build_config.h"
24 #include "perfetto/base/compiler.h"
25 #include "perfetto/base/export.h"
26 
27 // Ignore GCC warning about a missing argument for a variadic macro parameter.
28 #pragma GCC system_header
29 
30 // TODO(primiano): move this to base/build_config.h, turn into
31 // PERFETTO_BUILDFLAG(DCHECK_IS_ON) and update call sites to use that instead.
32 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
33 #define PERFETTO_DCHECK_IS_ON() 0
34 #else
35 #define PERFETTO_DCHECK_IS_ON() 1
36 #endif
37 
38 #if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_ON)
39 #define PERFETTO_DLOG_IS_ON() 1
40 #elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_OFF)
41 #define PERFETTO_DLOG_IS_ON() 0
42 #else
43 #define PERFETTO_DLOG_IS_ON() PERFETTO_DCHECK_IS_ON()
44 #endif
45 
46 #if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
47 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
48     !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
49 #error "Async-safe logging is limited to Android tree builds"
50 #endif
51 // For binaries which need a very lightweight logging implementation.
52 // Note that this header is incompatible with android/log.h.
53 #include <async_safe/log.h>
54 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
55 // Normal android logging.
56 #include <android/log.h>
57 #endif
58 
59 namespace perfetto {
60 namespace base {
61 
62 // Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
StrEnd(const char * s)63 constexpr const char* StrEnd(const char* s) {
64   return *s ? StrEnd(s + 1) : s;
65 }
66 
BasenameRecursive(const char * s,const char * begin,const char * end)67 constexpr const char* BasenameRecursive(const char* s,
68                                         const char* begin,
69                                         const char* end) {
70   return (*s == '/' && s < end)
71              ? (s + 1)
72              : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
73 }
74 
Basename(const char * str)75 constexpr const char* Basename(const char* str) {
76   return BasenameRecursive(StrEnd(str), str, StrEnd(str));
77 }
78 
79 enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError };
80 
81 PERFETTO_EXPORT void LogMessage(LogLev,
82                                 const char* fname,
83                                 int line,
84                                 const char* fmt,
85                                 ...) PERFETTO_PRINTF_FORMAT(4, 5);
86 
87 #if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
88 #define PERFETTO_XLOG(level, fmt, ...)                                        \
89   do {                                                                        \
90     async_safe_format_log((ANDROID_LOG_DEBUG + level), "perfetto",            \
91                           "%s:%d " fmt, ::perfetto::base::Basename(__FILE__), \
92                           __LINE__, ##__VA_ARGS__);                           \
93   } while (0)
94 #else  // defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
95 #define PERFETTO_XLOG(level, fmt, ...)                                      \
96   ::perfetto::base::LogMessage(level, ::perfetto::base::Basename(__FILE__), \
97                                __LINE__, fmt, ##__VA_ARGS__)
98 #endif  // defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
99 
100 #define PERFETTO_IMMEDIATE_CRASH() \
101   do {                             \
102     __builtin_trap();              \
103     __builtin_unreachable();       \
104   } while (0)
105 
106 #if PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
107 #define PERFETTO_LOG(fmt, ...) \
108   PERFETTO_XLOG(::perfetto::base::kLogInfo, fmt, ##__VA_ARGS__)
109 #else  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
110 #define PERFETTO_LOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
111 #endif  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
112 
113 #define PERFETTO_ILOG(fmt, ...) \
114   PERFETTO_XLOG(::perfetto::base::kLogImportant, fmt, ##__VA_ARGS__)
115 #define PERFETTO_ELOG(fmt, ...) \
116   PERFETTO_XLOG(::perfetto::base::kLogError, fmt, ##__VA_ARGS__)
117 #define PERFETTO_FATAL(fmt, ...)       \
118   do {                                 \
119     PERFETTO_PLOG(fmt, ##__VA_ARGS__); \
120     PERFETTO_IMMEDIATE_CRASH();        \
121   } while (0)
122 
123 #define PERFETTO_PLOG(x, ...) \
124   PERFETTO_ELOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
125 
126 #if PERFETTO_DLOG_IS_ON()
127 
128 #define PERFETTO_DLOG(fmt, ...) \
129   PERFETTO_XLOG(::perfetto::base::kLogDebug, fmt, ##__VA_ARGS__)
130 
131 #define PERFETTO_DPLOG(x, ...) \
132   PERFETTO_DLOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
133 
134 #else  // PERFETTO_DLOG_IS_ON()
135 
136 #define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
137 #define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
138 
139 #endif  // PERFETTO_DLOG_IS_ON()
140 
141 #if PERFETTO_DCHECK_IS_ON()
142 
143 #define PERFETTO_DCHECK(x)                           \
144   do {                                               \
145     if (PERFETTO_UNLIKELY(!(x))) {                   \
146       PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \
147       PERFETTO_IMMEDIATE_CRASH();                    \
148     }                                                \
149   } while (0)
150 
151 #define PERFETTO_CHECK(x) PERFETTO_DCHECK(x)
152 
153 #define PERFETTO_DFATAL(fmt, ...)      \
154   do {                                 \
155     PERFETTO_PLOG(fmt, ##__VA_ARGS__); \
156     PERFETTO_IMMEDIATE_CRASH();        \
157   } while (0)
158 
159 #define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__)
160 
161 #else  // PERFETTO_DCHECK_IS_ON()
162 
163 #define PERFETTO_DCHECK(x) \
164   do {                     \
165   } while (false && (x))
166 
167 #define PERFETTO_CHECK(x)                            \
168   do {                                               \
169     if (PERFETTO_UNLIKELY(!(x))) {                   \
170       PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \
171       PERFETTO_IMMEDIATE_CRASH();                    \
172     }                                                \
173   } while (0)
174 
175 #define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__)
176 #define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__)
177 
178 #endif  // PERFETTO_DCHECK_IS_ON()
179 
180 }  // namespace base
181 }  // namespace perfetto
182 
183 #endif  // INCLUDE_PERFETTO_BASE_LOGGING_H_
184