28 changes: 16 additions & 12 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,29 @@ using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;

static constexpr Log::Category g_categories[] = {
{{"async"}, {"log asynchronous activity"}, GDBR_LOG_ASYNC},
{{"break"}, {"log breakpoints"}, GDBR_LOG_BREAKPOINTS},
{{"comm"}, {"log communication activity"}, GDBR_LOG_COMM},
{{"packets"}, {"log gdb remote packets"}, GDBR_LOG_PACKETS},
{{"memory"}, {"log memory reads and writes"}, GDBR_LOG_MEMORY},
{{"async"}, {"log asynchronous activity"}, GDBRLog::Async},
{{"break"}, {"log breakpoints"}, GDBRLog::Breakpoints},
{{"comm"}, {"log communication activity"}, GDBRLog::Comm},
{{"packets"}, {"log gdb remote packets"}, GDBRLog::Packets},
{{"memory"}, {"log memory reads and writes"}, GDBRLog::Memory},
{{"data-short"},
{"log memory bytes for memory reads and writes for short transactions "
"only"},
GDBR_LOG_MEMORY_DATA_SHORT},
GDBRLog::MemoryDataShort},
{{"data-long"},
{"log memory bytes for memory reads and writes for all transactions"},
GDBR_LOG_MEMORY_DATA_LONG},
{{"process"}, {"log process events and activities"}, GDBR_LOG_PROCESS},
{{"step"}, {"log step related activities"}, GDBR_LOG_STEP},
{{"thread"}, {"log thread events and activities"}, GDBR_LOG_THREAD},
{{"watch"}, {"log watchpoint related activities"}, GDBR_LOG_WATCHPOINTS},
GDBRLog::MemoryDataLong},
{{"process"}, {"log process events and activities"}, GDBRLog::Process},
{{"step"}, {"log step related activities"}, GDBRLog::Step},
{{"thread"}, {"log thread events and activities"}, GDBRLog::Thread},
{{"watch"}, {"log watchpoint related activities"}, GDBRLog::Watchpoints},
};

Log::Channel ProcessGDBRemoteLog::g_channel(g_categories, GDBR_LOG_DEFAULT);
static Log::Channel g_channel(g_categories, GDBRLog::Packets);

template <> Log::Channel &lldb_private::LogChannelFor<GDBRLog>() {
return g_channel;
}

void ProcessGDBRemoteLog::Initialize() {
static llvm::once_flag g_once_flag;
Expand Down
55 changes: 36 additions & 19 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,52 @@

#include "lldb/Utility/Log.h"

#define GDBR_LOG_PROCESS (1u << 1)
#define GDBR_LOG_THREAD (1u << 2)
#define GDBR_LOG_PACKETS (1u << 3)
#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
#define GDBR_LOG_MEMORY_DATA_SHORT \
(1u << 5) // Log short memory reads/writes bytes
#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
#define GDBR_LOG_BREAKPOINTS (1u << 7)
#define GDBR_LOG_WATCHPOINTS (1u << 8)
#define GDBR_LOG_STEP (1u << 9)
#define GDBR_LOG_COMM (1u << 10)
#define GDBR_LOG_ASYNC (1u << 11)
#define GDBR_LOG_ALL (UINT32_MAX)
#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS

namespace lldb_private {
namespace process_gdb_remote {

class ProcessGDBRemoteLog {
static Log::Channel g_channel;
enum class GDBRLog : Log::MaskType {
Async = Log::ChannelFlag<0>,
Breakpoints = Log::ChannelFlag<1>,
Comm = Log::ChannelFlag<2>,
Memory = Log::ChannelFlag<3>, // Log memory reads/writes calls
MemoryDataLong = Log::ChannelFlag<4>, // Log all memory reads/writes bytes
MemoryDataShort = Log::ChannelFlag<5>, // Log short memory reads/writes bytes
Packets = Log::ChannelFlag<6>,
Process = Log::ChannelFlag<7>,
Step = Log::ChannelFlag<8>,
Thread = Log::ChannelFlag<9>,
Watchpoints = Log::ChannelFlag<10>,
LLVM_MARK_AS_BITMASK_ENUM(Watchpoints)
};

#define GDBR_LOG_PROCESS ::lldb_private::process_gdb_remote::GDBRLog::Process
#define GDBR_LOG_THREAD ::lldb_private::process_gdb_remote::GDBRLog::Thread
#define GDBR_LOG_PACKETS ::lldb_private::process_gdb_remote::GDBRLog::Packets
#define GDBR_LOG_MEMORY ::lldb_private::process_gdb_remote::GDBRLog::Memory
#define GDBR_LOG_MEMORY_DATA_SHORT \
::lldb_private::process_gdb_remote::GDBRLog::MemoryDataShort
#define GDBR_LOG_MEMORY_DATA_LONG \
::lldb_private::process_gdb_remote::GDBRLog::MemoryDataLong
#define GDBR_LOG_BREAKPOINTS \
::lldb_private::process_gdb_remote::GDBRLog::Breakpoints
#define GDBR_LOG_WATCHPOINTS \
::lldb_private::process_gdb_remote::GDBRLog::Watchpoints
#define GDBR_LOG_STEP ::lldb_private::process_gdb_remote::GDBRLog::Step
#define GDBR_LOG_COMM ::lldb_private::process_gdb_remote::GDBRLog::Comm
#define GDBR_LOG_ASYNC ::lldb_private::process_gdb_remote::GDBRLog::Async

class ProcessGDBRemoteLog {
public:
static void Initialize();

static Log *GetLogIfAllCategoriesSet(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
static Log *GetLogIfAnyCategoryIsSet(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
static Log *GetLogIfAllCategoriesSet(GDBRLog mask) { return GetLog(mask); }
static Log *GetLogIfAnyCategoryIsSet(GDBRLog mask) { return GetLog(mask); }
};

} // namespace process_gdb_remote

template <> Log::Channel &LogChannelFor<process_gdb_remote::GDBRLog>();

} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
8 changes: 4 additions & 4 deletions lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
Log *log = GetLog(GDBRLog::Thread);
LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),
GetID());
// At this point we can clone reg_info for architectures supporting
Expand All @@ -54,7 +54,7 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)

ThreadGDBRemote::~ThreadGDBRemote() {
ProcessSP process_sp(GetProcess());
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
Log *log = GetLog(GDBRLog::Thread);
LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this,
process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
DestroyThread();
Expand Down Expand Up @@ -222,7 +222,7 @@ void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(
StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
StructuredData::ObjectSP object_sp;
const lldb::user_id_t tid = GetProtocolID();
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
Log *log = GetLog(GDBRLog::Thread);
LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);
ProcessSP process_sp(GetProcess());
if (process_sp) {
Expand All @@ -236,7 +236,7 @@ StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
void ThreadGDBRemote::WillResume(StateType resume_state) {
int signo = GetResumeSignal();
const lldb::user_id_t tid = GetProtocolID();
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
Log *log = GetLog(GDBRLog::Thread);
LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
StateAsCString(resume_state));

Expand Down
18 changes: 10 additions & 8 deletions lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@ using namespace lldb_private;
static constexpr Log::Category g_categories[] = {
{{"comp"},
{"log insertions of object files into DWARF debug maps"},
DWARF_LOG_TYPE_COMPLETION},
{{"info"}, {"log the parsing of .debug_info"}, DWARF_LOG_DEBUG_INFO},
{{"line"}, {"log the parsing of .debug_line"}, DWARF_LOG_DEBUG_LINE},
DWARFLog::TypeCompletion},
{{"info"}, {"log the parsing of .debug_info"}, DWARFLog::DebugInfo},
{{"line"}, {"log the parsing of .debug_line"}, DWARFLog::DebugLine},
{{"lookups"},
{"log any lookups that happen by name, regex, or address"},
DWARF_LOG_LOOKUPS},
{{"map"},
{"log struct/unions/class type completions"},
DWARF_LOG_DEBUG_MAP},
DWARFLog::Lookups},
{{"map"}, {"log struct/unions/class type completions"}, DWARFLog::DebugMap},
};

Log::Channel LogChannelDWARF::g_channel(g_categories, DWARF_LOG_DEFAULT);
static Log::Channel g_channel(g_categories, DWARFLog::DebugInfo);

template <> Log::Channel &lldb_private::LogChannelFor<DWARFLog>() {
return g_channel;
}

void LogChannelDWARF::Initialize() {
Log::Register("dwarf", g_channel);
Expand Down
33 changes: 20 additions & 13 deletions lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,32 @@

#include "lldb/Utility/Log.h"

#define DWARF_LOG_DEBUG_INFO (1u << 1)
#define DWARF_LOG_DEBUG_LINE (1u << 2)
#define DWARF_LOG_LOOKUPS (1u << 3)
#define DWARF_LOG_TYPE_COMPLETION (1u << 4)
#define DWARF_LOG_DEBUG_MAP (1u << 5)
#define DWARF_LOG_ALL (UINT32_MAX)
#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)

namespace lldb_private {
class LogChannelDWARF {
static Log::Channel g_channel;

enum class DWARFLog : Log::MaskType {
DebugInfo = Log::ChannelFlag<0>,
DebugLine = Log::ChannelFlag<1>,
DebugMap = Log::ChannelFlag<2>,
Lookups = Log::ChannelFlag<3>,
TypeCompletion = Log::ChannelFlag<4>,
LLVM_MARK_AS_BITMASK_ENUM(TypeCompletion)
};
#define DWARF_LOG_DEBUG_INFO ::lldb_private::DWARFLog::DebugInfo
#define DWARF_LOG_DEBUG_LINE ::lldb_private::DWARFLog::DebugLine
#define DWARF_LOG_LOOKUPS ::lldb_private::DWARFLog::Lookups
#define DWARF_LOG_TYPE_COMPLETION ::lldb_private::DWARFLog::TypeCompletion
#define DWARF_LOG_DEBUG_MAP ::lldb_private::DWARFLog::DebugMap

class LogChannelDWARF {
public:
static void Initialize();
static void Terminate();

static Log *GetLogIfAll(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
static Log *GetLogIfAll(DWARFLog mask) { return GetLog(mask); }
static Log *GetLogIfAny(DWARFLog mask) { return GetLog(mask); }
};
}

template <> Log::Channel &LogChannelFor<DWARFLog>();
} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H
4 changes: 2 additions & 2 deletions lldb/source/Utility/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void Log::Enable(const std::shared_ptr<llvm::raw_ostream> &stream_sp,
uint32_t options, uint32_t flags) {
llvm::sys::ScopedWriter lock(m_mutex);

uint32_t mask = m_mask.fetch_or(flags, std::memory_order_relaxed);
MaskType mask = m_mask.fetch_or(flags, std::memory_order_relaxed);
if (mask | flags) {
m_options.store(options, std::memory_order_relaxed);
m_stream_sp = stream_sp;
Expand All @@ -99,7 +99,7 @@ void Log::Enable(const std::shared_ptr<llvm::raw_ostream> &stream_sp,
void Log::Disable(uint32_t flags) {
llvm::sys::ScopedWriter lock(m_mutex);

uint32_t mask = m_mask.fetch_and(~flags, std::memory_order_relaxed);
MaskType mask = m_mask.fetch_and(~flags, std::memory_order_relaxed);
if (!(mask & ~flags)) {
m_stream_sp.reset();
m_channel.log_ptr.store(nullptr, std::memory_order_relaxed);
Expand Down
97 changes: 61 additions & 36 deletions lldb/source/Utility/Logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,74 @@
using namespace lldb_private;

static constexpr Log::Category g_categories[] = {
{{"api"}, {"log API calls and return values"}, LIBLLDB_LOG_API},
{{"ast"}, {"log AST"}, LIBLLDB_LOG_AST},
{{"break"}, {"log breakpoints"}, LIBLLDB_LOG_BREAKPOINTS},
{{"commands"}, {"log command argument parsing"}, LIBLLDB_LOG_COMMANDS},
{{"comm"}, {"log communication activities"}, LIBLLDB_LOG_COMMUNICATION},
{{"conn"}, {"log connection details"}, LIBLLDB_LOG_CONNECTION},
{{"demangle"}, {"log mangled names to catch demangler crashes"}, LIBLLDB_LOG_DEMANGLE},
{{"dyld"}, {"log shared library related activities"}, LIBLLDB_LOG_DYNAMIC_LOADER},
{{"event"}, {"log broadcaster, listener and event queue activities"}, LIBLLDB_LOG_EVENTS},
{{"expr"}, {"log expressions"}, LIBLLDB_LOG_EXPRESSIONS},
{{"formatters"}, {"log data formatters related activities"}, LIBLLDB_LOG_DATAFORMATTERS},
{{"host"}, {"log host activities"}, LIBLLDB_LOG_HOST},
{{"jit"}, {"log JIT events in the target"}, LIBLLDB_LOG_JIT_LOADER},
{{"language"}, {"log language runtime events"}, LIBLLDB_LOG_LANGUAGE},
{{"mmap"}, {"log mmap related activities"}, LIBLLDB_LOG_MMAP},
{{"module"}, {"log module activities such as when modules are created, destroyed, replaced, and more"}, LIBLLDB_LOG_MODULES},
{{"object"}, {"log object construction/destruction for important objects"}, LIBLLDB_LOG_OBJECT},
{{"os"}, {"log OperatingSystem plugin related activities"}, LIBLLDB_LOG_OS},
{{"platform"}, {"log platform events and activities"}, LIBLLDB_LOG_PLATFORM},
{{"process"}, {"log process events and activities"}, LIBLLDB_LOG_PROCESS},
{{"script"}, {"log events about the script interpreter"}, LIBLLDB_LOG_SCRIPT},
{{"state"}, {"log private and public process state changes"}, LIBLLDB_LOG_STATE},
{{"step"}, {"log step related activities"}, LIBLLDB_LOG_STEP},
{{"symbol"}, {"log symbol related issues and warnings"}, LIBLLDB_LOG_SYMBOLS},
{{"system-runtime"}, {"log system runtime events"}, LIBLLDB_LOG_SYSTEM_RUNTIME},
{{"target"}, {"log target events and activities"}, LIBLLDB_LOG_TARGET},
{{"temp"}, {"log internal temporary debug messages"}, LIBLLDB_LOG_TEMPORARY},
{{"thread"}, {"log thread events and activities"}, LIBLLDB_LOG_THREAD},
{{"types"}, {"log type system related activities"}, LIBLLDB_LOG_TYPES},
{{"unwind"}, {"log stack unwind activities"}, LIBLLDB_LOG_UNWIND},
{{"watch"}, {"log watchpoint related activities"}, LIBLLDB_LOG_WATCHPOINTS},
{{"api"}, {"log API calls and return values"}, LLDBLog::API},
{{"ast"}, {"log AST"}, LLDBLog::AST},
{{"break"}, {"log breakpoints"}, LLDBLog::Breakpoints},
{{"commands"}, {"log command argument parsing"}, LLDBLog::Commands},
{{"comm"}, {"log communication activities"}, LLDBLog::Communication},
{{"conn"}, {"log connection details"}, LLDBLog::Connection},
{{"demangle"},
{"log mangled names to catch demangler crashes"},
LLDBLog::Demangle},
{{"dyld"},
{"log shared library related activities"},
LLDBLog::DynamicLoader},
{{"event"},
{"log broadcaster, listener and event queue activities"},
LLDBLog::Events},
{{"expr"}, {"log expressions"}, LLDBLog::Expressions},
{{"formatters"},
{"log data formatters related activities"},
LLDBLog::DataFormatters},
{{"host"}, {"log host activities"}, LLDBLog::Host},
{{"jit"}, {"log JIT events in the target"}, LLDBLog::JITLoader},
{{"language"}, {"log language runtime events"}, LLDBLog::Language},
{{"mmap"}, {"log mmap related activities"}, LLDBLog::MMap},
{{"module"},
{"log module activities such as when modules are created, destroyed, "
"replaced, and more"},
LLDBLog::Modules},
{{"object"},
{"log object construction/destruction for important objects"},
LLDBLog::Object},
{{"os"}, {"log OperatingSystem plugin related activities"}, LLDBLog::OS},
{{"platform"}, {"log platform events and activities"}, LLDBLog::Platform},
{{"process"}, {"log process events and activities"}, LLDBLog::Process},
{{"script"}, {"log events about the script interpreter"}, LLDBLog::Script},
{{"state"},
{"log private and public process state changes"},
LLDBLog::State},
{{"step"}, {"log step related activities"}, LLDBLog::Step},
{{"symbol"}, {"log symbol related issues and warnings"}, LLDBLog::Symbols},
{{"system-runtime"}, {"log system runtime events"}, LLDBLog::SystemRuntime},
{{"target"}, {"log target events and activities"}, LLDBLog::Target},
{{"temp"}, {"log internal temporary debug messages"}, LLDBLog::Temporary},
{{"thread"}, {"log thread events and activities"}, LLDBLog::Thread},
{{"types"}, {"log type system related activities"}, LLDBLog::Types},
{{"unwind"}, {"log stack unwind activities"}, LLDBLog::Unwind},
{{"watch"}, {"log watchpoint related activities"}, LLDBLog::Watchpoints},
};

static Log::Channel g_log_channel(g_categories, LIBLLDB_LOG_DEFAULT);
static Log::Channel g_log_channel(g_categories,
LLDBLog::Process | LLDBLog::Thread |
LLDBLog::DynamicLoader |
LLDBLog::Breakpoints |
LLDBLog::Watchpoints | LLDBLog::Step |
LLDBLog::State | LLDBLog::Symbols |
LLDBLog::Target | LLDBLog::Commands);

template <> Log::Channel &lldb_private::LogChannelFor<LLDBLog>() {
return g_log_channel;
}

void lldb_private::InitializeLldbChannel() {
Log::Register("lldb", g_log_channel);
}

Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) {
return g_log_channel.GetLogIfAll(mask);
Log *lldb_private::GetLogIfAllCategoriesSet(LLDBLog mask) {
return GetLog(mask);
}

Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) {
return g_log_channel.GetLogIfAny(mask);
Log *lldb_private::GetLogIfAnyCategoriesSet(LLDBLog mask) {
return GetLog(mask);
}
1 change: 1 addition & 0 deletions lldb/tools/lldb-server/lldb-gdbserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "lldb/Host/Socket.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/Status.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/ArgList.h"
Expand Down
60 changes: 37 additions & 23 deletions lldb/unittests/Utility/LogTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,24 @@
using namespace lldb;
using namespace lldb_private;

enum { FOO = 1, BAR = 2 };
enum class TestChannel : Log::MaskType {
FOO = Log::ChannelFlag<0>,
BAR = Log::ChannelFlag<1>,
LLVM_MARK_AS_BITMASK_ENUM(BAR),
};

LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();

static constexpr Log::Category test_categories[] = {
{{"foo"}, {"log foo"}, FOO}, {{"bar"}, {"log bar"}, BAR},
{{"foo"}, {"log foo"}, TestChannel::FOO},
{{"bar"}, {"log bar"}, TestChannel::BAR},
};
static constexpr uint32_t default_flags = FOO;

static Log::Channel test_channel(test_categories, default_flags);
static Log::Channel test_channel(test_categories, TestChannel::FOO);

namespace lldb_private {
template <> Log::Channel &LogChannelFor<TestChannel>() { return test_channel; }
} // namespace lldb_private

// Wrap enable, disable and list functions to make them easier to test.
static bool EnableChannel(std::shared_ptr<llvm::raw_ostream> stream_sp,
Expand Down Expand Up @@ -93,7 +104,7 @@ void LogChannelEnabledTest::SetUp() {
std::string error;
ASSERT_TRUE(EnableChannel(m_stream_sp, 0, "chan", {}, error));

m_log = test_channel.GetLogIfAll(FOO);
m_log = GetLog(TestChannel::FOO);
ASSERT_NE(nullptr, m_log);
}

Expand Down Expand Up @@ -124,18 +135,18 @@ TEST(LogTest, Register) {
TEST(LogTest, Unregister) {
llvm::llvm_shutdown_obj obj;
Log::Register("chan", test_channel);
EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message));
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {"foo"}, llvm::nulls()));
EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO));
EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
Log::Unregister("chan");
EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
}

TEST_F(LogChannelTest, Enable) {
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message));
Expand All @@ -144,53 +155,56 @@ TEST_F(LogChannelTest, Enable) {
EXPECT_EQ("Invalid log channel 'chanchan'.\n", error);

EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, error));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::BAR));

EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"bar"}, error));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(
Log::MaskType(TestChannel::FOO | TestChannel::BAR)));

EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"baz"}, error));
EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'"))
<< "error: " << error;
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(
Log::MaskType(TestChannel::FOO | TestChannel::BAR)));
}

TEST_F(LogChannelTest, EnableOptions) {
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message));
std::string error;
EXPECT_TRUE(
EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", {}, error));

Log *log = test_channel.GetLogIfAll(FOO);
Log *log = GetLog(TestChannel::FOO);
ASSERT_NE(nullptr, log);
EXPECT_TRUE(log->GetVerbose());
}

TEST_F(LogChannelTest, Disable) {
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message));
std::string error;
EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"foo", "bar"}, error));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(
Log::MaskType(TestChannel::FOO | TestChannel::BAR)));

EXPECT_TRUE(DisableChannel("chan", {"bar"}, error));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::BAR));

EXPECT_TRUE(DisableChannel("chan", {"baz"}, error));
EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'"))
<< "error: " << error;
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
EXPECT_EQ(nullptr, GetLog(TestChannel::BAR));

EXPECT_TRUE(DisableChannel("chan", {}, error));
EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR));
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO | TestChannel::BAR));
}

TEST_F(LogChannelTest, List) {
Expand Down Expand Up @@ -309,5 +323,5 @@ TEST_F(LogChannelEnabledTest, LogGetLogThread) {

// The mask should be either zero of "FOO". In either case, we should not trip
// any undefined behavior (run the test under TSAN to verify this).
EXPECT_THAT(mask, testing::AnyOf(0, FOO));
EXPECT_THAT(mask, testing::AnyOf(0, Log::MaskType(TestChannel::FOO)));
}