JDevlieghere created this revision.
JDevlieghere added reviewers: labath, clayborg, kastiglione, mib.
Herald added a project: All.
JDevlieghere requested review of this revision.
This patch adds a new flag to `log enable` allowing the user to specify a log
handler. This makes it possible to enable logging to a circular buffer (D127937
<https://reviews.llvm.org/D127937>) or with OSLog (D128321
<https://reviews.llvm.org/D128321>) as well as the default stream handler. As
is the patch is more of an RFC/POC. It needs some cleaning up as well as a test
case, which I'll add if everyone is happy with the direction.
https://reviews.llvm.org/D128323
Files:
lldb/include/lldb/Core/Debugger.h
lldb/include/lldb/lldb-private-enumerations.h
lldb/source/API/SBDebugger.cpp
lldb/source/Commands/CommandObjectLog.cpp
lldb/source/Commands/Options.td
lldb/source/Core/Debugger.cpp
lldb/tools/lldb-test/lldb-test.cpp
Index: lldb/tools/lldb-test/lldb-test.cpp
===================================================================
--- lldb/tools/lldb-test/lldb-test.cpp
+++ lldb/tools/lldb-test/lldb-test.cpp
@@ -1120,7 +1120,7 @@
/*add_to_history*/ eLazyBoolNo, Result);
if (!opts::Log.empty())
- Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, 0, errs());
+ Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, 0, eLogHandlerStream, errs());
if (opts::BreakpointSubcommand)
return opts::breakpoint::evaluateBreakpoints(*Dbg);
Index: lldb/source/Core/Debugger.cpp
===================================================================
--- lldb/source/Core/Debugger.cpp
+++ lldb/source/Core/Debugger.cpp
@@ -1406,10 +1406,30 @@
debugger_id, once);
}
+static std::shared_ptr<LogHandler>
+CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close,
+ size_t buffer_size) {
+
+ switch (log_handler_kind) {
+ case eLogHandlerStream:
+ return std::make_shared<StreamLogHandler>(fd, should_close, buffer_size);
+ case eLogHandlerRotating:
+ return std::make_shared<RotatingLogHandler>(buffer_size);
+#if defined(__APPLE__)
+ case eLogHandlerOSLog:
+ return std::make_shared<OSLogLogHandler>();
+#endif
+ case eLogHandlerCallback:
+ return {};
+ }
+ return {};
+}
+
bool Debugger::EnableLog(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories,
llvm::StringRef log_file, uint32_t log_options,
- size_t buffer_size, llvm::raw_ostream &error_stream) {
+ size_t buffer_size, LogHandlerKind log_handler_kind,
+ llvm::raw_ostream &error_stream) {
const bool should_close = true;
std::shared_ptr<LogHandler> log_handler_sp;
@@ -1419,8 +1439,9 @@
log_options |=
LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
} else if (log_file.empty()) {
- log_handler_sp = std::make_shared<StreamLogHandler>(
- GetOutputFile().GetDescriptor(), !should_close, buffer_size);
+ log_handler_sp =
+ CreateLogHandler(log_handler_kind, GetOutputFile().GetDescriptor(),
+ !should_close, buffer_size);
} else {
auto pos = m_stream_handlers.find(log_file);
if (pos != m_stream_handlers.end())
@@ -1440,8 +1461,9 @@
return false;
}
- log_handler_sp = std::make_shared<StreamLogHandler>(
- (*file)->GetDescriptor(), should_close, buffer_size);
+ log_handler_sp =
+ CreateLogHandler(log_handler_kind, (*file)->GetDescriptor(),
+ !should_close, buffer_size);
m_stream_handlers[log_file] = log_handler_sp;
}
}
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -433,6 +433,8 @@
Desc<"Set the destination file to log to.">;
def log_buffer_size : Option<"buffer", "b">, Group<1>, Arg<"UnsignedInteger">,
Desc<"Set the log to be buffered, using the specified buffer size.">;
+ def log_handler : Option<"handler", "h">, Group<1>,
+ EnumArg<"Value", "LogHandlerType()">, Desc<"Use a custom handler.">;
def log_threadsafe : Option<"threadsafe", "t">, Group<1>,
Desc<"Enable thread safe logging to avoid interweaved log lines.">;
def log_verbose : Option<"verbose", "v">, Group<1>,
Index: lldb/source/Commands/CommandObjectLog.cpp
===================================================================
--- lldb/source/Commands/CommandObjectLog.cpp
+++ lldb/source/Commands/CommandObjectLog.cpp
@@ -11,6 +11,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionValueEnumeration.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Utility/Args.h"
@@ -22,6 +23,30 @@
using namespace lldb;
using namespace lldb_private;
+static constexpr OptionEnumValueElement g_log_handler_type[] = {
+ {
+ eLogHandlerStream,
+ "stream",
+ "Use the stream log handler",
+ },
+ {
+ eLogHandlerRotating,
+ "rotating",
+ "Use the rotating log handler",
+ },
+#if defined(__APPLE__)
+ {
+ eLogHandlerOSLog,
+ "oslog",
+ "Use the OSLog log handler",
+ },
+#endif
+};
+
+static constexpr OptionEnumValues LogHandlerType() {
+ return OptionEnumValues(g_log_handler_type);
+}
+
#define LLDB_OPTIONS_log_enable
#include "CommandOptions.inc"
@@ -94,6 +119,14 @@
error =
buffer_size.SetValueFromString(option_arg, eVarSetOperationAssign);
break;
+ case 'h':
+ handler = (LogHandlerKind)OptionArgParser::ToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
+ if (!error.Success())
+ error.SetErrorStringWithFormat(
+ "unrecognized value for log provider '%s'",
+ option_arg.str().c_str());
+ break;
case 't':
log_options |= LLDB_LOG_OPTION_THREADSAFE;
break;
@@ -131,6 +164,7 @@
void OptionParsingStarting(ExecutionContext *execution_context) override {
log_file.Clear();
buffer_size.Clear();
+ handler = eLogHandlerStream;
log_options = 0;
}
@@ -140,6 +174,7 @@
FileSpec log_file;
OptionValueUInt64 buffer_size;
+ LogHandlerKind handler = eLogHandlerStream;
uint32_t log_options = 0;
};
@@ -171,7 +206,8 @@
llvm::raw_string_ostream error_stream(error);
bool success = GetDebugger().EnableLog(
channel, args.GetArgumentArrayRef(), log_file, m_options.log_options,
- m_options.buffer_size.GetCurrentValue(), error_stream);
+ m_options.buffer_size.GetCurrentValue(), m_options.handler,
+ error_stream);
result.GetErrorStream() << error_stream.str();
if (success)
Index: lldb/source/API/SBDebugger.cpp
===================================================================
--- lldb/source/API/SBDebugger.cpp
+++ lldb/source/API/SBDebugger.cpp
@@ -1621,7 +1621,8 @@
std::string error;
llvm::raw_string_ostream error_stream(error);
return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "",
- log_options, /*buffer_size=*/0, error_stream);
+ log_options, /*buffer_size=*/0,
+ eLogHandlerStream, error_stream);
} else
return false;
}
Index: lldb/include/lldb/lldb-private-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-private-enumerations.h
+++ lldb/include/lldb/lldb-private-enumerations.h
@@ -222,6 +222,15 @@
StatisticMax = 4
};
+// Enumeration that can be used to specify a log handler.
+enum LogHandlerKind {
+ eLogHandlerStream,
+ eLogHandlerCallback,
+ eLogHandlerRotating,
+#if defined(__APPLE__)
+ eLogHandlerOSLog,
+#endif
+};
inline std::string GetStatDescription(lldb_private::StatisticKind K) {
switch (K) {
Index: lldb/include/lldb/Core/Debugger.h
===================================================================
--- lldb/include/lldb/Core/Debugger.h
+++ lldb/include/lldb/Core/Debugger.h
@@ -245,7 +245,8 @@
bool EnableLog(llvm::StringRef channel,
llvm::ArrayRef<const char *> categories,
llvm::StringRef log_file, uint32_t log_options,
- size_t buffer_size, llvm::raw_ostream &error_stream);
+ size_t buffer_size, LogHandlerKind log_handler_kind,
+ llvm::raw_ostream &error_stream);
void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton);
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits