1 //===-- Log.h ---------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_UTILITY_LOG_H 10 #define LLDB_UTILITY_LOG_H 11 12 #include "lldb/Utility/Flags.h" 13 #include "lldb/Utility/Logging.h" 14 #include "lldb/lldb-defines.h" 15 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/StringMap.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Support/Error.h" 21 #include "llvm/Support/FormatVariadic.h" 22 #include "llvm/Support/ManagedStatic.h" 23 #include "llvm/Support/RWMutex.h" 24 25 #include <atomic> 26 #include <cstdarg> 27 #include <cstdint> 28 #include <memory> 29 #include <string> 30 #include <type_traits> 31 32 namespace llvm { 33 class raw_ostream; 34 } 35 // Logging Options 36 #define LLDB_LOG_OPTION_THREADSAFE (1u << 0) 37 #define LLDB_LOG_OPTION_VERBOSE (1u << 1) 38 #define LLDB_LOG_OPTION_PREPEND_SEQUENCE (1u << 3) 39 #define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4) 40 #define LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD (1u << 5) 41 #define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6) 42 #define LLDB_LOG_OPTION_BACKTRACE (1U << 7) 43 #define LLDB_LOG_OPTION_APPEND (1U << 8) 44 #define LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION (1U << 9) 45 46 // Logging Functions 47 namespace lldb_private { 48 49 class Log final { 50 public: 51 // Description of a log channel category. 52 struct Category { 53 llvm::StringLiteral name; 54 llvm::StringLiteral description; 55 uint32_t flag; 56 }; 57 58 // This class describes a log channel. It also encapsulates the behavior 59 // necessary to enable a log channel in an atomic manner. 60 class Channel { 61 std::atomic<Log *> log_ptr; 62 friend class Log; 63 64 public: 65 const llvm::ArrayRef<Category> categories; 66 const uint32_t default_flags; 67 Channel(llvm::ArrayRef<Log::Category> categories,uint32_t default_flags)68 constexpr Channel(llvm::ArrayRef<Log::Category> categories, 69 uint32_t default_flags) 70 : log_ptr(nullptr), categories(categories), 71 default_flags(default_flags) {} 72 73 // This function is safe to call at any time. If the channel is disabled 74 // after (or concurrently with) this function returning a non-null Log 75 // pointer, it is still safe to attempt to write to the Log object -- the 76 // output will be discarded. GetLogIfAll(uint32_t mask)77 Log *GetLogIfAll(uint32_t mask) { 78 Log *log = log_ptr.load(std::memory_order_relaxed); 79 if (log && log->GetMask().AllSet(mask)) 80 return log; 81 return nullptr; 82 } 83 84 // This function is safe to call at any time. If the channel is disabled 85 // after (or concurrently with) this function returning a non-null Log 86 // pointer, it is still safe to attempt to write to the Log object -- the 87 // output will be discarded. GetLogIfAny(uint32_t mask)88 Log *GetLogIfAny(uint32_t mask) { 89 Log *log = log_ptr.load(std::memory_order_relaxed); 90 if (log && log->GetMask().AnySet(mask)) 91 return log; 92 return nullptr; 93 } 94 }; 95 96 97 static void Initialize(); 98 99 // Static accessors for logging channels 100 static void Register(llvm::StringRef name, Channel &channel); 101 static void Unregister(llvm::StringRef name); 102 103 static bool 104 EnableLogChannel(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, 105 uint32_t log_options, llvm::StringRef channel, 106 llvm::ArrayRef<const char *> categories, 107 llvm::raw_ostream &error_stream); 108 109 static bool DisableLogChannel(llvm::StringRef channel, 110 llvm::ArrayRef<const char *> categories, 111 llvm::raw_ostream &error_stream); 112 113 static bool ListChannelCategories(llvm::StringRef channel, 114 llvm::raw_ostream &stream); 115 116 /// Returns the list of log channels. 117 static std::vector<llvm::StringRef> ListChannels(); 118 /// Calls the given lambda for every category in the given channel. 119 /// If no channel with the given name exists, lambda is never called. 120 static void ForEachChannelCategory( 121 llvm::StringRef channel, 122 llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda); 123 124 static void DisableAllLogChannels(); 125 126 static void ListAllLogChannels(llvm::raw_ostream &stream); 127 128 // Member functions 129 // 130 // These functions are safe to call at any time you have a Log* obtained from 131 // the Channel class. If logging is disabled between you obtaining the Log 132 // object and writing to it, the output will be silently discarded. Log(Channel & channel)133 Log(Channel &channel) : m_channel(channel) {} 134 ~Log() = default; 135 136 void PutCString(const char *cstr); 137 void PutString(llvm::StringRef str); 138 139 template <typename... Args> Format(llvm::StringRef file,llvm::StringRef function,const char * format,Args &&...args)140 void Format(llvm::StringRef file, llvm::StringRef function, 141 const char *format, Args &&... args) { 142 Format(file, function, llvm::formatv(format, std::forward<Args>(args)...)); 143 } 144 145 template <typename... Args> FormatError(llvm::Error error,llvm::StringRef file,llvm::StringRef function,const char * format,Args &&...args)146 void FormatError(llvm::Error error, llvm::StringRef file, 147 llvm::StringRef function, const char *format, 148 Args &&... args) { 149 Format(file, function, 150 llvm::formatv(format, llvm::toString(std::move(error)), 151 std::forward<Args>(args)...)); 152 } 153 154 /// Prefer using LLDB_LOGF whenever possible. 155 void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); 156 157 void Error(const char *fmt, ...) __attribute__((format(printf, 2, 3))); 158 159 void Verbose(const char *fmt, ...) __attribute__((format(printf, 2, 3))); 160 161 void Warning(const char *fmt, ...) __attribute__((format(printf, 2, 3))); 162 163 const Flags GetOptions() const; 164 165 const Flags GetMask() const; 166 167 bool GetVerbose() const; 168 169 void VAPrintf(const char *format, va_list args); 170 void VAError(const char *format, va_list args); 171 172 private: 173 Channel &m_channel; 174 175 // The mutex makes sure enable/disable operations are thread-safe. The 176 // options and mask variables are atomic to enable their reading in 177 // Channel::GetLogIfAny without taking the mutex to speed up the fast path. 178 // Their modification however, is still protected by this mutex. 179 llvm::sys::RWMutex m_mutex; 180 181 std::shared_ptr<llvm::raw_ostream> m_stream_sp; 182 std::atomic<uint32_t> m_options{0}; 183 std::atomic<uint32_t> m_mask{0}; 184 185 void WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file, 186 llvm::StringRef function); 187 void WriteMessage(const std::string &message); 188 189 void Format(llvm::StringRef file, llvm::StringRef function, 190 const llvm::formatv_object_base &payload); 191 GetStream()192 std::shared_ptr<llvm::raw_ostream> GetStream() { 193 llvm::sys::ScopedReader lock(m_mutex); 194 return m_stream_sp; 195 } 196 197 void Enable(const std::shared_ptr<llvm::raw_ostream> &stream_sp, 198 uint32_t options, uint32_t flags); 199 200 void Disable(uint32_t flags); 201 202 typedef llvm::StringMap<Log> ChannelMap; 203 static llvm::ManagedStatic<ChannelMap> g_channel_map; 204 205 static void ForEachCategory( 206 const Log::ChannelMap::value_type &entry, 207 llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda); 208 209 static void ListCategories(llvm::raw_ostream &stream, 210 const ChannelMap::value_type &entry); 211 static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry, 212 llvm::ArrayRef<const char *> categories); 213 214 static void DisableLoggingChild(); 215 216 Log(const Log &) = delete; 217 void operator=(const Log &) = delete; 218 }; 219 220 } // namespace lldb_private 221 222 /// The LLDB_LOG* macros defined below are the way to emit log messages. 223 /// 224 /// Note that the macros surround the arguments in a check for the log 225 /// being on, so you can freely call methods in arguments without affecting 226 /// the non-log execution flow. 227 /// 228 /// If you need to do more complex computations to prepare the log message 229 /// be sure to add your own if (log) check, since we don't want logging to 230 /// have any effect when not on. 231 /// 232 /// However, the LLDB_LOG macro uses the llvm::formatv system (see the 233 /// ProgrammersManual page in the llvm docs for more details). This allows 234 /// the use of "format_providers" to auto-format datatypes, and there are 235 /// already formatters for some of the llvm and lldb datatypes. 236 /// 237 /// So if you need to do non-trivial formatting of one of these types, be 238 /// sure to grep the lldb and llvm sources for "format_provider" to see if 239 /// there is already a formatter before doing in situ formatting, and if 240 /// possible add a provider if one does not already exist. 241 242 #define LLDB_LOG(log, ...) \ 243 do { \ 244 ::lldb_private::Log *log_private = (log); \ 245 if (log_private) \ 246 log_private->Format(__FILE__, __func__, __VA_ARGS__); \ 247 } while (0) 248 249 #define LLDB_LOGF(log, ...) \ 250 do { \ 251 ::lldb_private::Log *log_private = (log); \ 252 if (log_private) \ 253 log_private->Printf(__VA_ARGS__); \ 254 } while (0) 255 256 #define LLDB_LOGV(log, ...) \ 257 do { \ 258 ::lldb_private::Log *log_private = (log); \ 259 if (log_private && log_private->GetVerbose()) \ 260 log_private->Format(__FILE__, __func__, __VA_ARGS__); \ 261 } while (0) 262 263 // Write message to log, if error is set. In the log message refer to the error 264 // with {0}. Error is cleared regardless of whether logging is enabled. 265 #define LLDB_LOG_ERROR(log, error, ...) \ 266 do { \ 267 ::lldb_private::Log *log_private = (log); \ 268 ::llvm::Error error_private = (error); \ 269 if (log_private && error_private) { \ 270 log_private->FormatError(::std::move(error_private), __FILE__, __func__, \ 271 __VA_ARGS__); \ 272 } else \ 273 ::llvm::consumeError(::std::move(error_private)); \ 274 } while (0) 275 276 #endif // LLDB_UTILITY_LOG_H 277