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 <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> // For strerror. 24 25 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) 26 #define PERFETTO_DCHECK_IS_ON() 0 27 #else 28 #define PERFETTO_DCHECK_IS_ON() 1 29 #endif 30 31 #if !defined(PERFETTO_FORCE_DLOG) 32 #define PERFETTO_DLOG_IS_ON() PERFETTO_DCHECK_IS_ON() 33 #else 34 #define PERFETTO_DLOG_IS_ON() PERFETTO_FORCE_DLOG 35 #endif 36 37 #include "perfetto/base/build_config.h" 38 #include "perfetto/base/utils.h" 39 40 #if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG) 41 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \ 42 !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) 43 #error "Async-safe logging is limited to Android tree builds" 44 #endif 45 // For binaries which need a very lightweight logging implementation. 46 // Note that this header is incompatible with android/log.h. 47 #include <async_safe/log.h> 48 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) 49 // Normal android logging. 50 #include <android/log.h> 51 #endif 52 53 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 54 #include <unistd.h> 55 #endif 56 57 namespace perfetto { 58 namespace base { 59 60 // Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c . 61 constexpr const char* StrEnd(const char* s) { 62 return *s ? StrEnd(s + 1) : s; 63 } 64 65 constexpr const char* BasenameRecursive(const char* s, 66 const char* begin, 67 const char* end) { 68 return (*s == '/' && s < end) 69 ? (s + 1) 70 : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s); 71 } 72 73 constexpr const char* Basename(const char* str) { 74 return BasenameRecursive(StrEnd(str), str, StrEnd(str)); 75 } 76 77 #define PERFETTO_LOG_LINE__(x) #x 78 #define PERFETTO_LOG_LINE_(x) PERFETTO_LOG_LINE__(x) 79 #define PERFETTO_LOG_LINE PERFETTO_LOG_LINE_(__LINE__) 80 81 enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError }; 82 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) 83 // The escape sequences don't work in a Windows command prompt. 84 #define PERFETTO_XLOG_STDERR(level, fmt, ...) \ 85 fprintf(stderr, "%-24.24s " fmt "\n", \ 86 ::perfetto::base::Basename(__FILE__ "(" PERFETTO_LOG_LINE "):"), \ 87 ##__VA_ARGS__) 88 #else 89 constexpr const char* kLogFmt[] = {"\x1b[2m", "\x1b[39m", "\x1b[32m\x1b[1m", 90 "\x1b[31m"}; 91 92 #define PERFETTO_XLOG_STDERR(level, fmt, ...) \ 93 fprintf(stderr, "\x1b[90m%-24.24s\x1b[0m %s" fmt "\x1b[0m\n", \ 94 ::perfetto::base::Basename(__FILE__ ":" PERFETTO_LOG_LINE), \ 95 ::perfetto::base::kLogFmt[::perfetto::base::LogLev::level], \ 96 ##__VA_ARGS__) 97 #endif 98 99 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \ 100 defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG) 101 #define PERFETTO_XLOG(level, fmt, ...) \ 102 do { \ 103 async_safe_format_log( \ 104 (ANDROID_LOG_DEBUG + ::perfetto::base::LogLev::level), "perfetto", \ 105 "%s " fmt, ::perfetto::base::Basename(__FILE__ ":" PERFETTO_LOG_LINE), \ 106 ##__VA_ARGS__); \ 107 } while (0) 108 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) 109 // Standard logging marco on Android - log to both stderr and logcat. When part 110 // of the Android tree, stderr points to /dev/null so logcat is the only way to 111 // get some logging. 112 #define PERFETTO_XLOG(level, fmt, ...) \ 113 do { \ 114 __android_log_print( \ 115 (ANDROID_LOG_DEBUG + ::perfetto::base::LogLev::level), "perfetto", \ 116 "%s " fmt, ::perfetto::base::Basename(__FILE__ ":" PERFETTO_LOG_LINE), \ 117 ##__VA_ARGS__); \ 118 PERFETTO_XLOG_STDERR(level, fmt, ##__VA_ARGS__); \ 119 } while (0) 120 #else 121 #define PERFETTO_XLOG PERFETTO_XLOG_STDERR 122 #endif 123 124 #define PERFETTO_IMMEDIATE_CRASH() \ 125 do { \ 126 __builtin_trap(); \ 127 __builtin_unreachable(); \ 128 } while (0) 129 130 #define PERFETTO_LOG(fmt, ...) PERFETTO_XLOG(kLogInfo, fmt, ##__VA_ARGS__) 131 #define PERFETTO_ILOG(fmt, ...) PERFETTO_XLOG(kLogImportant, fmt, ##__VA_ARGS__) 132 #define PERFETTO_ELOG(fmt, ...) PERFETTO_XLOG(kLogError, fmt, ##__VA_ARGS__) 133 #define PERFETTO_FATAL(fmt, ...) \ 134 do { \ 135 PERFETTO_PLOG(fmt, ##__VA_ARGS__); \ 136 PERFETTO_IMMEDIATE_CRASH(); \ 137 } while (0) 138 139 #define PERFETTO_PLOG(x, ...) \ 140 PERFETTO_ELOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno)) 141 142 #if PERFETTO_DLOG_IS_ON() 143 144 #define PERFETTO_DLOG(fmt, ...) PERFETTO_XLOG(kLogDebug, fmt, ##__VA_ARGS__) 145 146 #define PERFETTO_DPLOG(x, ...) \ 147 PERFETTO_DLOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno)) 148 149 #else 150 151 #define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__) 152 #define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__) 153 154 #endif // PERFETTO_DLOG_IS_ON() 155 156 #if PERFETTO_DCHECK_IS_ON() 157 158 #define PERFETTO_DCHECK(x) \ 159 do { \ 160 if (PERFETTO_UNLIKELY(!(x))) { \ 161 PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \ 162 PERFETTO_IMMEDIATE_CRASH(); \ 163 } \ 164 } while (0) 165 166 #define PERFETTO_DFATAL(fmt, ...) \ 167 do { \ 168 PERFETTO_PLOG(fmt, ##__VA_ARGS__); \ 169 PERFETTO_IMMEDIATE_CRASH(); \ 170 } while (0) 171 172 #define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__) 173 174 #else 175 176 #define PERFETTO_DCHECK(x) \ 177 do { \ 178 } while (false && (x)) 179 180 #define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__) 181 #define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__) 182 183 #endif // PERFETTO_DCHECK_IS_ON() 184 185 #if PERFETTO_DCHECK_IS_ON() 186 #define PERFETTO_CHECK(x) PERFETTO_DCHECK(x) 187 #else 188 #define PERFETTO_CHECK(x) \ 189 do { \ 190 if (PERFETTO_UNLIKELY(!(x))) { \ 191 PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \ 192 PERFETTO_IMMEDIATE_CRASH(); \ 193 } \ 194 } while (0) 195 196 #endif // PERFETTO_DCHECK_IS_ON() 197 198 } // namespace base 199 } // namespace perfetto 200 201 #endif // INCLUDE_PERFETTO_BASE_LOGGING_H_ 202