• 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 #if defined(__GNUC__) || defined(__clang__)
28 // Ignore GCC warning about a missing argument for a variadic macro parameter.
29 #pragma GCC system_header
30 #endif
31 
32 #if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_ON)
33 #define PERFETTO_DCHECK_IS_ON() 1
34 #elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_OFF)
35 #define PERFETTO_DCHECK_IS_ON() 0
36 #elif defined(DCHECK_ALWAYS_ON) ||                                         \
37     (!defined(NDEBUG) && (PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
38                           PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD) ||   \
39                           PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)))
40 #define PERFETTO_DCHECK_IS_ON() 1
41 #else
42 #define PERFETTO_DCHECK_IS_ON() 0
43 #endif
44 
45 #if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_ON)
46 #define PERFETTO_DLOG_IS_ON() 1
47 #elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_OFF)
48 #define PERFETTO_DLOG_IS_ON() 0
49 #else
50 #define PERFETTO_DLOG_IS_ON() PERFETTO_DCHECK_IS_ON()
51 #endif
52 
53 #if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
54 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
55     !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
56 #error "Async-safe logging is limited to Android tree builds"
57 #endif
58 // For binaries which need a very lightweight logging implementation.
59 // Note that this header is incompatible with android/log.h.
60 #include <async_safe/log.h>
61 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
62 // Normal android logging.
63 #include <android/log.h>
64 #endif
65 
66 // Enable the "Print the most recent PERFETTO_LOG(s) before crashing" feature
67 // on Android in-tree builds and on standalone builds (mainly for testing).
68 // This is deliberately no PERFETTO_OS_ANDROID because we don't want this
69 // feature when perfetto is embedded in other Android projects (e.g. SDK).
70 // TODO(b/203795298): TFLite is using the client library in blaze builds and is
71 // targeting API 19. For now disable the feature based on API level.
72 #if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
73 #define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
74 #elif PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
75 #define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
76 #elif PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
77     (!PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) ||       \
78      (defined(__ANDROID_API__) && __ANDROID_API__ >= 21))
79 #define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
80 #else
81 #define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
82 #endif
83 
84 namespace perfetto {
85 namespace base {
86 
87 // Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
StrEnd(const char * s)88 constexpr const char* StrEnd(const char* s) {
89   return *s ? StrEnd(s + 1) : s;
90 }
91 
BasenameRecursive(const char * s,const char * begin,const char * end)92 constexpr const char* BasenameRecursive(const char* s,
93                                         const char* begin,
94                                         const char* end) {
95   return (*s == '/' && s < end)
96              ? (s + 1)
97              : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
98 }
99 
Basename(const char * str)100 constexpr const char* Basename(const char* str) {
101   return BasenameRecursive(StrEnd(str), str, StrEnd(str));
102 }
103 
104 enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError };
105 
106 struct LogMessageCallbackArgs {
107   LogLev level;
108   int line;
109   const char* filename;
110   const char* message;
111 };
112 
113 using LogMessageCallback = void (*)(LogMessageCallbackArgs);
114 
115 // This is not thread safe and must be called before using tracing from other
116 // threads.
117 PERFETTO_EXPORT void SetLogMessageCallback(LogMessageCallback callback);
118 
119 PERFETTO_EXPORT void LogMessage(LogLev,
120                                 const char* fname,
121                                 int line,
122                                 const char* fmt,
123                                 ...) PERFETTO_PRINTF_FORMAT(4, 5);
124 
125 // This is defined in debug_crash_stack_trace.cc, but that is only linked in
126 // standalone && debug builds, see enable_perfetto_stderr_crash_dump in
127 // perfetto.gni.
128 PERFETTO_EXPORT void EnableStacktraceOnCrashForDebug();
129 
130 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
131 // Gets a snapshot of the logs from the internal log ring buffer and:
132 // - On Android in-tree builds: Passes that to android_set_abort_message().
133 //   That will attach the logs to the crash report.
134 // - On standalone builds (all otther OSes) prints that on stderr.
135 // This function must called only once, right before inducing a crash (This is
136 // because android_set_abort_message() can only be called once).
137 PERFETTO_EXPORT void MaybeSerializeLastLogsForCrashReporting();
138 #else
MaybeSerializeLastLogsForCrashReporting()139 inline void MaybeSerializeLastLogsForCrashReporting() {}
140 #endif
141 
142 #if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
143 #define PERFETTO_XLOG(level, fmt, ...)                                        \
144   do {                                                                        \
145     async_safe_format_log((ANDROID_LOG_DEBUG + level), "perfetto",            \
146                           "%s:%d " fmt, ::perfetto::base::Basename(__FILE__), \
147                           __LINE__, ##__VA_ARGS__);                           \
148   } while (0)
149 #elif defined(PERFETTO_DISABLE_LOG)
150 #define PERFETTO_XLOG(level, fmt, ...) ::perfetto::base::ignore_result(level, \
151                                 fmt, ##__VA_ARGS__)
152 #else
153 #define PERFETTO_XLOG(level, fmt, ...)                                      \
154   ::perfetto::base::LogMessage(level, ::perfetto::base::Basename(__FILE__), \
155                                __LINE__, fmt, ##__VA_ARGS__)
156 #endif
157 
158 #if defined(_MSC_VER)
159 #define PERFETTO_IMMEDIATE_CRASH()                               \
160   do {                                                           \
161     ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
162     __debugbreak();                                              \
163     __assume(0);                                                 \
164   } while (0)
165 #else
166 #define PERFETTO_IMMEDIATE_CRASH()                               \
167   do {                                                           \
168     ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
169     __builtin_trap();                                            \
170     __builtin_unreachable();                                     \
171   } while (0)
172 #endif
173 
174 #if PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
175 #define PERFETTO_LOG(fmt, ...) \
176   PERFETTO_XLOG(::perfetto::base::kLogInfo, fmt, ##__VA_ARGS__)
177 #else  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
178 #define PERFETTO_LOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
179 #endif  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
180 
181 #define PERFETTO_ILOG(fmt, ...) \
182   PERFETTO_XLOG(::perfetto::base::kLogImportant, fmt, ##__VA_ARGS__)
183 #define PERFETTO_ELOG(fmt, ...) \
184   PERFETTO_XLOG(::perfetto::base::kLogError, fmt, ##__VA_ARGS__)
185 #define PERFETTO_FATAL(fmt, ...)       \
186   do {                                 \
187     PERFETTO_PLOG(fmt, ##__VA_ARGS__); \
188     PERFETTO_IMMEDIATE_CRASH();        \
189   } while (0)
190 
191 #if defined(__GNUC__) || defined(__clang__)
192 #define PERFETTO_PLOG(x, ...) \
193   PERFETTO_ELOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
194 #else
195 // MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
196 #define PERFETTO_PLOG PERFETTO_ELOG
197 #endif
198 
199 #define PERFETTO_CHECK(x)                            \
200   do {                                               \
201     if (PERFETTO_UNLIKELY(!(x))) {                   \
202       PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \
203       PERFETTO_IMMEDIATE_CRASH();                    \
204     }                                                \
205   } while (0)
206 
207 #if PERFETTO_DLOG_IS_ON()
208 
209 #define PERFETTO_DLOG(fmt, ...) \
210   PERFETTO_XLOG(::perfetto::base::kLogDebug, fmt, ##__VA_ARGS__)
211 
212 #if defined(__GNUC__) || defined(__clang__)
213 #define PERFETTO_DPLOG(x, ...) \
214   PERFETTO_DLOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
215 #else
216 // MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
217 #define PERFETTO_DPLOG PERFETTO_DLOG
218 #endif
219 
220 #else  // PERFETTO_DLOG_IS_ON()
221 
222 #define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
223 #define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
224 
225 #endif  // PERFETTO_DLOG_IS_ON()
226 
227 #if PERFETTO_DCHECK_IS_ON()
228 
229 #define PERFETTO_DCHECK(x) PERFETTO_CHECK(x)
230 #define PERFETTO_DFATAL(...) PERFETTO_FATAL(__VA_ARGS__)
231 #define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__)
232 
233 #else  // PERFETTO_DCHECK_IS_ON()
234 
235 #define PERFETTO_DCHECK(x) \
236   do {                     \
237   } while (false && (x))
238 
239 #define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__)
240 #define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__)
241 
242 #endif  // PERFETTO_DCHECK_IS_ON()
243 
244 }  // namespace base
245 }  // namespace perfetto
246 
247 #endif  // INCLUDE_PERFETTO_BASE_LOGGING_H_
248