Remove lldb streams from the Log class completely

Summary:
previously we switched to llvm streams for log output, this completes
the switch for the error streams.

I also clean up the includes and remove the unused argument from
DisableAllLogChannels().

This required adding a bit of boiler plate to convert the output in the
command interpreter, but that should go away when we switch command
results to use llvm streams as well.

Reviewers: zturner, eugene

Subscribers: lldb-commits, emaste

Differential Revision: https://reviews.llvm.org/D30894

llvm-svn: 297812
This commit is contained in:
Pavel Labath 2017-03-15 09:06:58 +00:00
parent 6de25ec61a
commit 775588c0c3
14 changed files with 130 additions and 113 deletions

View File

@ -195,7 +195,7 @@ public:
bool EnableLog(llvm::StringRef channel, bool EnableLog(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories, llvm::ArrayRef<const char *> categories,
llvm::StringRef log_file, uint32_t log_options, llvm::StringRef log_file, uint32_t log_options,
Stream &error_stream); llvm::raw_ostream &error_stream);
void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton); void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton);

View File

@ -13,9 +13,9 @@
// Project includes // Project includes
#include "lldb/Utility/Flags.h" #include "lldb/Utility/Flags.h"
#include "lldb/Utility/Logging.h" #include "lldb/Utility/Logging.h"
#include "lldb/lldb-private.h"
// Other libraries and framework includes // Other libraries and framework includes
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/RWMutex.h" #include "llvm/Support/RWMutex.h"
@ -100,17 +100,17 @@ public:
EnableLogChannel(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, EnableLogChannel(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
uint32_t log_options, llvm::StringRef channel, uint32_t log_options, llvm::StringRef channel,
llvm::ArrayRef<const char *> categories, llvm::ArrayRef<const char *> categories,
Stream &error_stream); llvm::raw_ostream &error_stream);
static bool DisableLogChannel(llvm::StringRef channel, static bool DisableLogChannel(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories, llvm::ArrayRef<const char *> categories,
Stream &error_stream); llvm::raw_ostream &error_stream);
static bool ListChannelCategories(llvm::StringRef channel, Stream &stream); static bool ListChannelCategories(llvm::StringRef channel, llvm::raw_ostream &stream);
static void DisableAllLogChannels(Stream *feedback_strm); static void DisableAllLogChannels();
static void ListAllLogChannels(Stream *strm); static void ListAllLogChannels(llvm::raw_ostream &stream);
//------------------------------------------------------------------ //------------------------------------------------------------------
// Member functions // Member functions
@ -131,7 +131,6 @@ public:
Format(file, function, llvm::formatv(format, std::forward<Args>(args)...)); Format(file, function, llvm::formatv(format, std::forward<Args>(args)...));
} }
// CLEANUP: Add llvm::raw_ostream &Stream() function.
void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); void Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
void VAPrintf(const char *format, va_list args); void VAPrintf(const char *format, va_list args);
@ -183,12 +182,13 @@ private:
typedef llvm::StringMap<Log> ChannelMap; typedef llvm::StringMap<Log> ChannelMap;
static llvm::ManagedStatic<ChannelMap> g_channel_map; static llvm::ManagedStatic<ChannelMap> g_channel_map;
static void ListCategories(Stream &stream, static void ListCategories(llvm::raw_ostream &stream,
const ChannelMap::value_type &entry); const ChannelMap::value_type &entry);
static uint32_t GetFlags(Stream &stream, const ChannelMap::value_type &entry, static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
llvm::ArrayRef<const char *> categories); llvm::ArrayRef<const char *> categories);
DISALLOW_COPY_AND_ASSIGN(Log); Log(const Log &) = delete;
void operator=(const Log &) = delete;
}; };
} // namespace lldb_private } // namespace lldb_private

View File

@ -10,10 +10,7 @@
#ifndef LLDB_UTILITY_LOGGING_H #ifndef LLDB_UTILITY_LOGGING_H
#define LLDB_UTILITY_LOGGING_H #define LLDB_UTILITY_LOGGING_H
// Project includes #include <cstdint>
#include "lldb/lldb-private.h"
// Other libraries and framework includes
#include "llvm/Support/raw_ostream.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Log Bits specific to logging in lldb // Log Bits specific to logging in lldb
@ -56,6 +53,8 @@
namespace lldb_private { namespace lldb_private {
class Log;
void LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...); void LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...);
Log *GetLogIfAllCategoriesSet(uint32_t mask); Log *GetLogIfAllCategoriesSet(uint32_t mask);

View File

@ -1133,9 +1133,10 @@ bool SBDebugger::EnableLog(const char *channel, const char **categories) {
if (m_opaque_sp) { if (m_opaque_sp) {
uint32_t log_options = uint32_t log_options =
LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
StreamString errors; std::string error;
llvm::raw_string_ostream error_stream(error);
return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "", return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "",
log_options, errors); log_options, error_stream);
} else } else
return false; return false;
} }

View File

@ -170,9 +170,14 @@ protected:
m_options.log_file.GetPath(log_file, sizeof(log_file)); m_options.log_file.GetPath(log_file, sizeof(log_file));
else else
log_file[0] = '\0'; log_file[0] = '\0';
std::string error;
llvm::raw_string_ostream error_stream(error);
bool success = m_interpreter.GetDebugger().EnableLog( bool success = m_interpreter.GetDebugger().EnableLog(
channel, args.GetArgumentArrayRef(), log_file, m_options.log_options, channel, args.GetArgumentArrayRef(), log_file, m_options.log_options,
result.GetErrorStream()); error_stream);
result.GetErrorStream() << error_stream.str();
if (success) if (success)
result.SetStatus(eReturnStatusSuccessFinishNoResult); result.SetStatus(eReturnStatusSuccessFinishNoResult);
else else
@ -229,12 +234,15 @@ protected:
const std::string channel = args[0].ref; const std::string channel = args[0].ref;
args.Shift(); // Shift off the channel args.Shift(); // Shift off the channel
if (channel == "all") { if (channel == "all") {
Log::DisableAllLogChannels(&result.GetErrorStream()); Log::DisableAllLogChannels();
result.SetStatus(eReturnStatusSuccessFinishNoResult); result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else { } else {
std::string error;
llvm::raw_string_ostream error_stream(error);
if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(), if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(),
result.GetErrorStream())) error_stream))
result.SetStatus(eReturnStatusSuccessFinishNoResult); result.SetStatus(eReturnStatusSuccessFinishNoResult);
result.GetErrorStream() << error_stream.str();
} }
return result.Succeeded(); return result.Succeeded();
} }
@ -269,17 +277,20 @@ public:
protected: protected:
bool DoExecute(Args &args, CommandReturnObject &result) override { bool DoExecute(Args &args, CommandReturnObject &result) override {
std::string output;
llvm::raw_string_ostream output_stream(output);
if (args.empty()) { if (args.empty()) {
Log::ListAllLogChannels(&result.GetOutputStream()); Log::ListAllLogChannels(output_stream);
result.SetStatus(eReturnStatusSuccessFinishResult); result.SetStatus(eReturnStatusSuccessFinishResult);
} else { } else {
bool success = true; bool success = true;
for (const auto &entry : args.entries()) for (const auto &entry : args.entries())
success = success && Log::ListChannelCategories( success =
entry.ref, result.GetOutputStream()); success && Log::ListChannelCategories(entry.ref, output_stream);
if (success) if (success)
result.SetStatus(eReturnStatusSuccessFinishResult); result.SetStatus(eReturnStatusSuccessFinishResult);
} }
result.GetOutputStream() << output_stream.str();
return result.Succeeded(); return result.Succeeded();
} }
}; };

View File

@ -1242,7 +1242,7 @@ void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
bool Debugger::EnableLog(llvm::StringRef channel, bool Debugger::EnableLog(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories, llvm::ArrayRef<const char *> categories,
llvm::StringRef log_file, uint32_t log_options, llvm::StringRef log_file, uint32_t log_options,
Stream &error_stream) { llvm::raw_ostream &error_stream) {
const bool should_close = true; const bool should_close = true;
const bool unbuffered = true; const bool unbuffered = true;
@ -1266,7 +1266,7 @@ bool Debugger::EnableLog(llvm::StringRef channel,
int FD; int FD;
if (std::error_code ec = if (std::error_code ec =
llvm::sys::fs::openFileForWrite(log_file, FD, flags)) { llvm::sys::fs::openFileForWrite(log_file, FD, flags)) {
error_stream.Format("Unable to open log file: {0}", ec.message()); error_stream << "Unable to open log file: " << ec.message();
return false; return false;
} }
log_stream_sp.reset( log_stream_sp.reset(

View File

@ -93,9 +93,8 @@ static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd,
static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd, static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
const ProcessLaunchInfo &info) { const ProcessLaunchInfo &info) {
// First, make sure we disable all logging. If we are logging to stdout, our // First, make sure we disable all logging. If we are logging to stdout, our
// logs can be // logs can be mistaken for inferior output.
// mistaken for inferior output. Log::DisableAllLogChannels();
Log::DisableAllLogChannels(nullptr);
// Do not inherit setgid powers. // Do not inherit setgid powers.
if (setgid(getgid()) != 0) if (setgid(getgid()) != 0)

View File

@ -121,5 +121,5 @@ void SystemInitializerCommon::Terminate() {
#endif #endif
HostInfo::Terminate(); HostInfo::Terminate();
Log::DisableAllLogChannels(nullptr); Log::DisableAllLogChannels();
} }

View File

@ -12,7 +12,6 @@
#include "llvm/Support/Threading.h" #include "llvm/Support/Threading.h"
using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
static constexpr Log::Category g_categories[] = { static constexpr Log::Category g_categories[] = {

View File

@ -9,7 +9,6 @@
#include "LogChannelDWARF.h" #include "LogChannelDWARF.h"
using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
static constexpr Log::Category g_categories[] = { static constexpr Log::Category g_categories[] = {

View File

@ -9,10 +9,8 @@
// Project includes // Project includes
#include "lldb/Utility/Log.h" #include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/VASPrintf.h" #include "lldb/Utility/VASPrintf.h"
#include "lldb/lldb-types.h"
// Other libraries and framework includes // Other libraries and framework includes
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
@ -32,20 +30,20 @@
#include <mutex> #include <mutex>
#include <string> #include <string>
using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map; llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map;
void Log::ListCategories(Stream &stream, const ChannelMap::value_type &entry) { void Log::ListCategories(llvm::raw_ostream &stream, const ChannelMap::value_type &entry) {
stream.Format("Logging categories for '{0}':\n", entry.first()); stream << llvm::formatv("Logging categories for '{0}':\n", entry.first());
stream.Format(" all - all available logging categories\n"); stream << " all - all available logging categories\n";
stream.Format(" default - default set of logging categories\n"); stream << " default - default set of logging categories\n";
for (const auto &category : entry.second.m_channel.categories) for (const auto &category : entry.second.m_channel.categories)
stream.Format(" {0} - {1}\n", category.name, category.description); stream << llvm::formatv(" {0} - {1}\n", category.name,
category.description);
} }
uint32_t Log::GetFlags(Stream &stream, const ChannelMap::value_type &entry, uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
llvm::ArrayRef<const char *> categories) { llvm::ArrayRef<const char *> categories) {
bool list_categories = false; bool list_categories = false;
uint32_t flags = 0; uint32_t flags = 0;
@ -65,7 +63,8 @@ uint32_t Log::GetFlags(Stream &stream, const ChannelMap::value_type &entry,
flags |= cat->flag; flags |= cat->flag;
continue; continue;
} }
stream.Format("error: unrecognized log category '{0}'\n", category); stream << llvm::formatv("error: unrecognized log category '{0}'\n",
category);
list_categories = true; list_categories = true;
} }
if (list_categories) if (list_categories)
@ -194,10 +193,10 @@ void Log::Unregister(llvm::StringRef name) {
bool Log::EnableLogChannel( bool Log::EnableLogChannel(
const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
uint32_t log_options, llvm::StringRef channel, uint32_t log_options, llvm::StringRef channel,
llvm::ArrayRef<const char *> categories, Stream &error_stream) { llvm::ArrayRef<const char *> categories, llvm::raw_ostream &error_stream) {
auto iter = g_channel_map->find(channel); auto iter = g_channel_map->find(channel);
if (iter == g_channel_map->end()) { if (iter == g_channel_map->end()) {
error_stream.Format("Invalid log channel '{0}'.\n", channel); error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel);
return false; return false;
} }
uint32_t flags = categories.empty() uint32_t flags = categories.empty()
@ -209,10 +208,10 @@ bool Log::EnableLogChannel(
bool Log::DisableLogChannel(llvm::StringRef channel, bool Log::DisableLogChannel(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories, llvm::ArrayRef<const char *> categories,
Stream &error_stream) { llvm::raw_ostream &error_stream) {
auto iter = g_channel_map->find(channel); auto iter = g_channel_map->find(channel);
if (iter == g_channel_map->end()) { if (iter == g_channel_map->end()) {
error_stream.Format("Invalid log channel '{0}'.\n", channel); error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel);
return false; return false;
} }
uint32_t flags = categories.empty() uint32_t flags = categories.empty()
@ -222,30 +221,32 @@ bool Log::DisableLogChannel(llvm::StringRef channel,
return true; return true;
} }
bool Log::ListChannelCategories(llvm::StringRef channel, Stream &stream) { bool Log::ListChannelCategories(llvm::StringRef channel,
llvm::raw_ostream &stream) {
auto ch = g_channel_map->find(channel); auto ch = g_channel_map->find(channel);
if (ch == g_channel_map->end()) { if (ch == g_channel_map->end()) {
stream.Format("Invalid log channel '{0}'.\n", channel); stream << llvm::formatv("Invalid log channel '{0}'.\n", channel);
return false; return false;
} }
ListCategories(stream, *ch); ListCategories(stream, *ch);
return true; return true;
} }
void Log::DisableAllLogChannels(Stream *feedback_strm) { void Log::DisableAllLogChannels() {
for (auto &entry : *g_channel_map) for (auto &entry : *g_channel_map)
entry.second.Disable(UINT32_MAX); entry.second.Disable(UINT32_MAX);
} }
void Log::ListAllLogChannels(Stream *strm) { void Log::ListAllLogChannels(llvm::raw_ostream &stream) {
if (g_channel_map->empty()) { if (g_channel_map->empty()) {
strm->PutCString("No logging channels are currently registered.\n"); stream << "No logging channels are currently registered.\n";
return; return;
} }
for (const auto &channel : *g_channel_map) for (const auto &channel : *g_channel_map)
ListCategories(*strm, channel); ListCategories(stream, channel);
} }
bool Log::GetVerbose() const { bool Log::GetVerbose() const {
return m_options.load(std::memory_order_relaxed) & LLDB_LOG_OPTION_VERBOSE; return m_options.load(std::memory_order_relaxed) & LLDB_LOG_OPTION_VERBOSE;
} }

View File

@ -8,17 +8,8 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "lldb/Utility/Logging.h" #include "lldb/Utility/Logging.h"
// C Includes
// C++ Includes
#include <atomic>
#include <cstring>
// Other libraries and framework includes
// Project includes
#include "lldb/Utility/Log.h" #include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
static constexpr Log::Category g_categories[] = { static constexpr Log::Category g_categories[] = {

View File

@ -46,7 +46,8 @@ bool LLDBServerUtilities::SetupLogging(const std::string &log_file,
SmallVector<StringRef, 32> channel_array; SmallVector<StringRef, 32> channel_array;
log_channels.split(channel_array, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false); log_channels.split(channel_array, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);
for (auto channel_with_categories : channel_array) { for (auto channel_with_categories : channel_array) {
StreamString error_stream; std::string error;
llvm::raw_string_ostream error_stream(error);
Args channel_then_categories(channel_with_categories); Args channel_then_categories(channel_with_categories);
std::string channel(channel_then_categories.GetArgumentAtIndex(0)); std::string channel(channel_then_categories.GetArgumentAtIndex(0));
channel_then_categories.Shift(); // Shift off the channel channel_then_categories.Shift(); // Shift off the channel
@ -55,8 +56,8 @@ bool LLDBServerUtilities::SetupLogging(const std::string &log_file,
log_stream_sp, log_options, channel, log_stream_sp, log_options, channel,
channel_then_categories.GetArgumentArrayRef(), error_stream); channel_then_categories.GetArgumentArrayRef(), error_stream);
if (!success) { if (!success) {
fprintf(stderr, "Unable to open log file '%s' for channel \"%s\"\n", errs() << formatv("Unable to setup logging for channel \"{0}\": {1}",
log_file.c_str(), channel_with_categories.str().c_str()); channel, error_stream.str());
return false; return false;
} }
} }

View File

@ -27,7 +27,7 @@ static constexpr uint32_t default_flags = FOO;
static Log::Channel test_channel(test_categories, default_flags); static Log::Channel test_channel(test_categories, default_flags);
struct LogChannelTest : public ::testing::Test { struct LogChannelTest : public ::testing::Test {
void TearDown() override { Log::DisableAllLogChannels(nullptr); } void TearDown() override { Log::DisableAllLogChannels(); }
static void SetUpTestCase() { static void SetUpTestCase() {
Log::Register("chan", test_channel); Log::Register("chan", test_channel);
@ -39,6 +39,31 @@ struct LogChannelTest : public ::testing::Test {
} }
}; };
// Wrap enable, disable and list functions to make them easier to test.
static bool EnableChannel(std::shared_ptr<llvm::raw_ostream> stream_sp,
uint32_t log_options, llvm::StringRef channel,
llvm::ArrayRef<const char *> categories,
std::string &error) {
error.clear();
llvm::raw_string_ostream error_stream(error);
return Log::EnableLogChannel(stream_sp, log_options, channel, categories,
error_stream);
}
static bool DisableChannel(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories,
std::string &error) {
error.clear();
llvm::raw_string_ostream error_stream(error);
return Log::DisableLogChannel(channel, categories, error_stream);
}
static bool ListCategories(llvm::StringRef channel, std::string &result) {
result.clear();
llvm::raw_string_ostream result_stream(result);
return Log::ListChannelCategories(channel, result_stream);
}
TEST(LogTest, LLDB_LOG_nullptr) { TEST(LogTest, LLDB_LOG_nullptr) {
Log *log = nullptr; Log *log = nullptr;
LLDB_LOG(log, "{0}", 0); // Shouldn't crash LLDB_LOG(log, "{0}", 0); // Shouldn't crash
@ -56,12 +81,10 @@ TEST(LogTest, Unregister) {
llvm::llvm_shutdown_obj obj; llvm::llvm_shutdown_obj obj;
Log::Register("chan", test_channel); Log::Register("chan", test_channel);
EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO)); EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
const char *cat1[] = {"foo"};
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {"foo"}, llvm::nulls()));
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat1, err));
EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO)); EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO));
Log::Unregister("chan"); Log::Unregister("chan");
EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO)); EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
@ -72,24 +95,20 @@ TEST_F(LogChannelTest, Enable) {
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string error;
EXPECT_FALSE(Log::EnableLogChannel(stream_sp, 0, "chanchan", {}, err)); ASSERT_FALSE(EnableChannel(stream_sp, 0, "chanchan", {}, error));
EXPECT_EQ("Invalid log channel 'chanchan'.\n", err.GetString()); EXPECT_EQ("Invalid log channel 'chanchan'.\n", error);
err.Clear();
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {}, err)); EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, error));
EXPECT_EQ("", err.GetString()) << "err: " << err.GetString().str();
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
const char *cat2[] = {"bar"}; EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"bar"}, error));
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat2, err));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
const char *cat3[] = {"baz"}; EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"baz"}, error));
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat3, err)); EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'"))
EXPECT_TRUE(err.GetString().contains("unrecognized log category 'baz'")) << "error: " << error;
<< "err: " << err.GetString().str();
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
} }
@ -98,9 +117,9 @@ TEST_F(LogChannelTest, EnableOptions) {
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string error;
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", EXPECT_TRUE(
{}, err)); EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", {}, error));
Log *log = test_channel.GetLogIfAll(FOO); Log *log = test_channel.GetLogIfAll(FOO);
ASSERT_NE(nullptr, log); ASSERT_NE(nullptr, log);
@ -109,34 +128,30 @@ TEST_F(LogChannelTest, EnableOptions) {
TEST_F(LogChannelTest, Disable) { TEST_F(LogChannelTest, Disable) {
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
const char *cat12[] = {"foo", "bar"};
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string error;
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat12, err)); EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"foo", "bar"}, error));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
const char *cat2[] = {"bar"}; EXPECT_TRUE(DisableChannel("chan", {"bar"}, error));
EXPECT_TRUE(Log::DisableLogChannel("chan", cat2, err));
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
const char *cat3[] = {"baz"}; EXPECT_TRUE(DisableChannel("chan", {"baz"}, error));
EXPECT_TRUE(Log::DisableLogChannel("chan", cat3, err)); EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'"))
EXPECT_TRUE(err.GetString().contains("unrecognized log category 'baz'")) << "error: " << error;
<< "err: " << err.GetString().str();
EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
err.Clear();
EXPECT_TRUE(Log::DisableLogChannel("chan", {}, err)); EXPECT_TRUE(DisableChannel("chan", {}, error));
EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR)); EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR));
} }
TEST_F(LogChannelTest, List) { TEST_F(LogChannelTest, List) {
StreamString str; std::string list;
EXPECT_TRUE(Log::ListChannelCategories("chan", str)); EXPECT_TRUE(ListCategories("chan", list));
std::string expected = std::string expected =
R"(Logging categories for 'chan': R"(Logging categories for 'chan':
all - all available logging categories all - all available logging categories
@ -144,11 +159,10 @@ TEST_F(LogChannelTest, List) {
foo - log foo foo - log foo
bar - log bar bar - log bar
)"; )";
EXPECT_EQ(expected, str.GetString().str()); EXPECT_EQ(expected, list);
str.Clear();
EXPECT_FALSE(Log::ListChannelCategories("chanchan", str)); EXPECT_FALSE(ListCategories("chanchan", list));
EXPECT_EQ("Invalid log channel 'chanchan'.\n", str.GetString().str()); EXPECT_EQ("Invalid log channel 'chanchan'.\n", list);
} }
static std::string GetLogString(uint32_t log_options, const char *format, static std::string GetLogString(uint32_t log_options, const char *format,
@ -156,14 +170,16 @@ static std::string GetLogString(uint32_t log_options, const char *format,
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string error;
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, log_options, "chan", {}, err)); llvm::raw_string_ostream error_stream(error);
EXPECT_TRUE(
Log::EnableLogChannel(stream_sp, log_options, "chan", {}, error_stream));
Log *log = test_channel.GetLogIfAll(FOO); Log *log = test_channel.GetLogIfAll(FOO);
EXPECT_NE(nullptr, log); EXPECT_NE(nullptr, log);
LLDB_LOG(log, format, arg); LLDB_LOG(log, format, arg);
EXPECT_TRUE(Log::DisableLogChannel("chan", {}, err)); EXPECT_TRUE(Log::DisableLogChannel("chan", {}, error_stream));
return stream_sp->str(); return stream_sp->str();
} }
@ -198,14 +214,14 @@ TEST_F(LogChannelTest, LogThread) {
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string err;
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {}, err)); EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, err));
Log *log = test_channel.GetLogIfAll(FOO); Log *log = test_channel.GetLogIfAll(FOO);
// Start logging on one thread. Concurrently, try disabling the log channel. // Start logging on one thread. Concurrently, try disabling the log channel.
std::thread log_thread([log] { LLDB_LOG(log, "Hello World"); }); std::thread log_thread([log] { LLDB_LOG(log, "Hello World"); });
EXPECT_TRUE(Log::DisableLogChannel("chan", {}, err)); EXPECT_TRUE(DisableChannel("chan", {}, err));
log_thread.join(); log_thread.join();
// The log thread either managed to write to the log in time, or it didn't. In // The log thread either managed to write to the log in time, or it didn't. In
@ -221,18 +237,18 @@ TEST_F(LogChannelTest, LogVerboseThread) {
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string err;
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {}, err)); EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, err));
Log *log = test_channel.GetLogIfAll(FOO); Log *log = test_channel.GetLogIfAll(FOO);
// Start logging on one thread. Concurrently, try enabling the log channel // Start logging on one thread. Concurrently, try enabling the log channel
// (with different log options). // (with different log options).
std::thread log_thread([log] { LLDB_LOGV(log, "Hello World"); }); std::thread log_thread([log] { LLDB_LOGV(log, "Hello World"); });
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", EXPECT_TRUE(EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan",
{}, err)); {}, err));
log_thread.join(); log_thread.join();
EXPECT_TRUE(Log::DisableLogChannel("chan", {}, err)); EXPECT_TRUE(DisableChannel("chan", {}, err));
// The log thread either managed to write to the log, or it didn't. In either // The log thread either managed to write to the log, or it didn't. In either
// case, we should not trip any undefined behavior (run the test under TSAN to // case, we should not trip any undefined behavior (run the test under TSAN to
@ -247,15 +263,15 @@ TEST_F(LogChannelTest, LogGetLogThread) {
std::string message; std::string message;
std::shared_ptr<llvm::raw_string_ostream> stream_sp( std::shared_ptr<llvm::raw_string_ostream> stream_sp(
new llvm::raw_string_ostream(message)); new llvm::raw_string_ostream(message));
StreamString err; std::string err;
EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {}, err)); EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, err));
Log *log = test_channel.GetLogIfAll(FOO); Log *log = test_channel.GetLogIfAll(FOO);
// Try fetching the log on one thread. Concurrently, try disabling the log // Try fetching the log on one thread. Concurrently, try disabling the log
// channel. // channel.
uint32_t mask; uint32_t mask;
std::thread log_thread([log, &mask] { mask = log->GetMask().Get(); }); std::thread log_thread([log, &mask] { mask = log->GetMask().Get(); });
EXPECT_TRUE(Log::DisableLogChannel("chan", {}, err)); EXPECT_TRUE(DisableChannel("chan", {}, err));
log_thread.join(); log_thread.join();
// The mask should be either zero of "FOO". In either case, we should not trip // The mask should be either zero of "FOO". In either case, we should not trip