9#ifndef LLDB_UTILITY_LOG_H
10#define LLDB_UTILITY_LOG_H
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/Error.h"
20#include "llvm/Support/FormatVariadic.h"
21#include "llvm/Support/ManagedStatic.h"
22#include "llvm/Support/RWMutex.h"
39#define LLDB_LOG_OPTION_VERBOSE (1u << 1)
40#define LLDB_LOG_OPTION_PREPEND_SEQUENCE (1u << 3)
41#define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4)
42#define LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD (1u << 5)
43#define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6)
44#define LLDB_LOG_OPTION_BACKTRACE (1U << 7)
45#define LLDB_LOG_OPTION_APPEND (1U << 8)
46#define LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION (1U << 9)
47#define LLDB_LOG_OPTION_JSON (1U << 10)
55 virtual void Emit(llvm::StringRef message) = 0;
57 virtual bool isA(
const void *ClassID)
const {
return ClassID == &
ID; }
69 void Emit(llvm::StringRef message)
override;
72 bool isA(
const void *ClassID)
const override {
return ClassID == &
ID; }
85 void Emit(llvm::StringRef message)
override;
87 bool isA(
const void *ClassID)
const override {
return ClassID == &
ID; }
100 void Emit(llvm::StringRef message)
override;
101 void Dump(llvm::raw_ostream &stream)
const;
103 bool isA(
const void *ClassID)
const override {
return ClassID == &
ID; }
123 std::shared_ptr<LogHandler> second_log_handler);
125 void Emit(llvm::StringRef message)
override;
127 bool isA(
const void *ClassID)
const override {
return ClassID == &
ID; }
147 template <MaskType Bit>
156 template <
typename Cat>
161 std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value);
175 template <
typename Cat>
181 std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value);
189 Log *log =
log_ptr.load(std::memory_order_relaxed);
190 if (log && ((log->
GetMask() & mask) != 0))
198 static void Register(llvm::StringRef name, Channel &channel);
203 uint32_t log_options, llvm::StringRef channel,
204 llvm::ArrayRef<const char *> categories);
207 llvm::ArrayRef<const char *> categories);
210 llvm::raw_ostream &output_stream,
211 llvm::raw_ostream &error_stream);
213 static llvm::Expected<std::string>
221 llvm::StringRef channel,
222 llvm::function_ref<
void(llvm::StringRef, llvm::StringRef)> lambda);
239 template <
typename...
Args>
240 void Format(llvm::StringRef file, llvm::StringRef function,
241 const char *format,
Args &&... args) {
242 Format(file, function, llvm::formatv(format, std::forward<Args>(args)...));
245 template <
typename...
Args>
247 llvm::StringRef function,
const char *format,
250 llvm::formatv(format, llvm::toString(std::move(
error)),
251 std::forward<Args>(args)...));
254 void Formatf(llvm::StringRef file, llvm::StringRef function,
255 const char *format, ...) __attribute__((format(printf, 4, 5)));
258 void Printf(const
char *format, ...) __attribute__((format(printf, 2, 3)));
260 void Verbose(const
char *fmt, ...) __attribute__((format(printf, 2, 3)));
268 void VAPrintf(const
char *format, va_list args);
270 const
char *format, va_list args);
273 std::optional<
MaskType> flags = std::nullopt,
274 uint32_t options = 0);
291 void WriteHeader(llvm::raw_ostream &
OS, llvm::StringRef file,
292 llvm::StringRef function);
294 llvm::StringRef function);
297 llvm::StringRef message);
299 void Format(llvm::StringRef file, llvm::StringRef function,
300 const llvm::formatv_object_base &payload);
303 llvm::sys::ScopedReader lock(
m_mutex);
307 bool Dump(llvm::raw_ostream &stream);
313 const Log::ChannelMap::value_type &entry,
314 llvm::function_ref<
void(llvm::StringRef, llvm::StringRef)> lambda);
317 const ChannelMap::value_type &entry);
323 static llvm::Expected<Log::MaskType>
324 GetFlags(
const ChannelMap::value_type &entry,
325 llvm::ArrayRef<const char *> categories);
340 std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value);
375#define LLDB_LOG(log, ...) \
377 ::lldb_private::Log *log_private = (log); \
379 log_private->Format(__FILE__, __func__, __VA_ARGS__); \
382#define LLDB_LOG_VERBOSE(log, ...) \
384 ::lldb_private::Log *log_private = (log); \
385 if (log_private && log_private->GetVerbose()) \
386 log_private->Format(__FILE__, __func__, __VA_ARGS__); \
389#define LLDB_LOGF(log, ...) \
391 ::lldb_private::Log *log_private = (log); \
393 log_private->Formatf(__FILE__, __func__, __VA_ARGS__); \
396#define LLDB_LOGF_VERBOSE(log, ...) \
398 ::lldb_private::Log *log_private = (log); \
399 if (log_private && log_private->GetVerbose()) \
400 log_private->Formatf(__FILE__, __func__, __VA_ARGS__); \
405#define LLDB_LOG_ERROR(log, error, ...) \
407 ::lldb_private::Log *log_private = (log); \
408 ::llvm::Error error_private = (error); \
410 log_private = lldb_private::GetLLDBErrorLog(); \
411 if (log_private && error_private) { \
412 log_private->FormatError(::std::move(error_private), __FILE__, __func__, \
415 ::llvm::consumeError(::std::move(error_private)); \
421#define LLDB_LOG_ERRORV(log, error, ...) \
423 ::lldb_private::Log *log_private = (log); \
424 ::llvm::Error error_private = (error); \
425 if (log_private && log_private->GetVerbose() && error_private) { \
426 log_private->FormatError(::std::move(error_private), __FILE__, __func__, \
429 ::llvm::consumeError(::std::move(error_private)); \
static llvm::raw_ostream & error(Stream &strm)
A command line argument class.
lldb::LogOutputCallback m_callback
static bool classof(const LogHandler *obj)
bool isA(const void *ClassID) const override
CallbackLogHandler(lldb::LogOutputCallback callback, void *baton)
void Emit(llvm::StringRef message) override
virtual void Emit(llvm::StringRef message)=0
virtual bool isA(const void *ClassID) const
static bool classof(const LogHandler *obj)
virtual ~LogHandler()=default
constexpr Channel(llvm::ArrayRef< Log::Category > categories, Cat default_flags)
Log * GetLog(MaskType mask)
const llvm::ArrayRef< Category > categories
std::atomic< Log * > log_ptr
const MaskType default_flags
llvm::sys::RWMutex m_mutex
static void ListCategories(llvm::raw_ostream &stream, const ChannelMap::value_type &entry)
std::shared_ptr< LogHandler > m_handler
void WriteMessage(llvm::StringRef message)
void PutCString(const char *cstr)
void EmitJSONMessage(llvm::StringRef file, llvm::StringRef function, llvm::StringRef message)
static void ForEachCategory(const Log::ChannelMap::value_type &entry, llvm::function_ref< void(llvm::StringRef, llvm::StringRef)> lambda)
static constexpr MaskType ChannelFlag
llvm::StringMap< Log > ChannelMap
void Formatf(llvm::StringRef file, llvm::StringRef function, const char *format,...) __attribute__((format(printf
uint64_t MaskType
The underlying type of all log channel enums.
static llvm::Error DisableLogChannel(llvm::StringRef channel, llvm::ArrayRef< const char * > categories)
static void Register(llvm::StringRef name, Channel &channel)
static void ListAllLogChannels(llvm::raw_ostream &stream)
void VAFormatf(llvm::StringRef file, llvm::StringRef function, const char *format, va_list args)
void WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file, llvm::StringRef function)
static bool DumpLogChannel(llvm::StringRef channel, llvm::raw_ostream &output_stream, llvm::raw_ostream &error_stream)
void VAPrintf(const char *format, va_list args)
void FormatError(llvm::Error error, llvm::StringRef file, llvm::StringRef function, const char *format, Args &&... args)
void Disable(std::optional< MaskType > flags=std::nullopt)
static llvm::Error EnableLogChannel(const std::shared_ptr< LogHandler > &log_handler_sp, uint32_t log_options, llvm::StringRef channel, llvm::ArrayRef< const char * > categories)
void WriteJSONHeader(llvm::json::Object &obj, llvm::StringRef file, llvm::StringRef function)
void Format(llvm::StringRef file, llvm::StringRef function, const char *format, Args &&... args)
static llvm::ManagedStatic< ChannelMap > g_channel_map
std::shared_ptr< LogHandler > GetHandler()
std::atomic< MaskType > m_mask
static void Unregister(llvm::StringRef name)
void Enable(const std::shared_ptr< LogHandler > &handler_sp, std::optional< MaskType > flags=std::nullopt, uint32_t options=0)
static void DisableAllLogChannels()
static void ForEachChannelCategory(llvm::StringRef channel, llvm::function_ref< void(llvm::StringRef, llvm::StringRef)> lambda)
Calls the given lambda for every category in the given channel.
void void void const Flags GetOptions() const
static llvm::Expected< std::string > ListChannelCategories(llvm::StringRef channel)
void operator=(const Log &)=delete
static std::vector< llvm::StringRef > ListChannels()
Returns the list of log channels.
static llvm::Expected< Log::MaskType > GetFlags(const ChannelMap::value_type &entry, llvm::ArrayRef< const char * > categories)
Convert an array of category names into a set of category flags.
void PutString(llvm::StringRef str)
bool Dump(llvm::raw_ostream &stream)
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
void void void Verbose(const char *fmt,...) __attribute__((format(printf
std::atomic< uint32_t > m_options
void Dump(llvm::raw_ostream &stream) const
std::unique_ptr< std::string[]> m_messages
bool isA(const void *ClassID) const override
void Emit(llvm::StringRef message) override
static bool classof(const LogHandler *obj)
size_t NormalizeIndex(size_t i) const
size_t GetNumMessages() const
RotatingLogHandler(size_t size)
size_t GetFirstMessageIndex() const
~StreamLogHandler() override
llvm::raw_fd_ostream m_stream
StreamLogHandler(int fd, bool should_close, size_t buffer_size=0)
void Emit(llvm::StringRef message) override
bool isA(const void *ClassID) const override
static bool classof(const LogHandler *obj)
void Emit(llvm::StringRef message) override
std::shared_ptr< LogHandler > m_first_log_handler
bool isA(const void *ClassID) const override
TeeLogHandler(std::shared_ptr< LogHandler > first_log_handler, std::shared_ptr< LogHandler > second_log_handler)
static bool classof(const LogHandler *obj)
std::shared_ptr< LogHandler > m_second_log_handler
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Log::Channel & LogChannelFor()=delete
void SetLLDBErrorLog(Log *log)
Getter and setter for the error log (see g_error_log).
void(* LogOutputCallback)(const char *, void *baton)
llvm::StringLiteral description
constexpr Category(llvm::StringLiteral name, llvm::StringLiteral description, Cat mask)