Skip to content

Commit 09dea54

Browse files
committed
[lldb] Support a buffered logging mode
This patch adds a buffered logging mode to lldb. A buffer size can be passed to `log enable` with the -b flag. If no buffer size is specified, logging is unbuffered. Differential revision: https://reviews.llvm.org/D127986
1 parent 734ad03 commit 09dea54

File tree

8 files changed

+35
-21
lines changed

8 files changed

+35
-21
lines changed

lldb/include/lldb/Core/Debugger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
245245
bool EnableLog(llvm::StringRef channel,
246246
llvm::ArrayRef<const char *> categories,
247247
llvm::StringRef log_file, uint32_t log_options,
248-
llvm::raw_ostream &error_stream);
248+
size_t buffer_size, llvm::raw_ostream &error_stream);
249249

250250
void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton);
251251

lldb/include/lldb/Utility/Log.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ class LogHandler {
5858

5959
class StreamLogHandler : public LogHandler {
6060
public:
61-
StreamLogHandler(int fd, bool should_close, bool unbuffered = true);
61+
StreamLogHandler(int fd, bool should_close, size_t buffer_size = 0);
62+
~StreamLogHandler() override;
6263

6364
void Emit(llvm::StringRef message) override;
65+
void Flush();
6466

6567
private:
6668
llvm::raw_fd_ostream m_stream;

lldb/source/API/SBDebugger.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1621,7 +1621,7 @@ bool SBDebugger::EnableLog(const char *channel, const char **categories) {
16211621
std::string error;
16221622
llvm::raw_string_ostream error_stream(error);
16231623
return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "",
1624-
log_options, error_stream);
1624+
log_options, /*buffer_size=*/0, error_stream);
16251625
} else
16261626
return false;
16271627
}

lldb/source/Commands/CommandObjectLog.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "lldb/Host/OptionParser.h"
1212
#include "lldb/Interpreter/CommandReturnObject.h"
1313
#include "lldb/Interpreter/OptionArgParser.h"
14+
#include "lldb/Interpreter/OptionValueUInt64.h"
1415
#include "lldb/Interpreter/Options.h"
1516
#include "lldb/Utility/Args.h"
1617
#include "lldb/Utility/FileSpec.h"
@@ -21,7 +22,7 @@
2122
using namespace lldb;
2223
using namespace lldb_private;
2324

24-
#define LLDB_OPTIONS_log
25+
#define LLDB_OPTIONS_log_enable
2526
#include "CommandOptions.inc"
2627

2728
/// Common completion logic for log enable/disable.
@@ -89,6 +90,10 @@ class CommandObjectLogEnable : public CommandObjectParsed {
8990
log_file.SetFile(option_arg, FileSpec::Style::native);
9091
FileSystem::Instance().Resolve(log_file);
9192
break;
93+
case 'b':
94+
error =
95+
buffer_size.SetValueFromString(option_arg, eVarSetOperationAssign);
96+
break;
9297
case 't':
9398
log_options |= LLDB_LOG_OPTION_THREADSAFE;
9499
break;
@@ -125,16 +130,16 @@ class CommandObjectLogEnable : public CommandObjectParsed {
125130

126131
void OptionParsingStarting(ExecutionContext *execution_context) override {
127132
log_file.Clear();
133+
buffer_size.Clear();
128134
log_options = 0;
129135
}
130136

131137
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
132-
return llvm::makeArrayRef(g_log_options);
138+
return llvm::makeArrayRef(g_log_enable_options);
133139
}
134140

135-
// Instance variables to hold the values for command options.
136-
137141
FileSpec log_file;
142+
OptionValueUInt64 buffer_size;
138143
uint32_t log_options = 0;
139144
};
140145

@@ -164,9 +169,9 @@ class CommandObjectLogEnable : public CommandObjectParsed {
164169

165170
std::string error;
166171
llvm::raw_string_ostream error_stream(error);
167-
bool success =
168-
GetDebugger().EnableLog(channel, args.GetArgumentArrayRef(), log_file,
169-
m_options.log_options, error_stream);
172+
bool success = GetDebugger().EnableLog(
173+
channel, args.GetArgumentArrayRef(), log_file, m_options.log_options,
174+
m_options.buffer_size.GetCurrentValue(), error_stream);
170175
result.GetErrorStream() << error_stream.str();
171176

172177
if (success)

lldb/source/Commands/Options.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,11 @@ let Command = "history" in {
428428
Desc<"Clears the current command history.">;
429429
}
430430

431-
let Command = "log" in {
431+
let Command = "log enable" in {
432432
def log_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
433433
Desc<"Set the destination file to log to.">;
434+
def log_buffer_size : Option<"buffer", "b">, Group<1>, Arg<"UnsignedInteger">,
435+
Desc<"Set the log to be buffered, using the specified buffer size.">;
434436
def log_threadsafe : Option<"threadsafe", "t">, Group<1>,
435437
Desc<"Enable thread safe logging to avoid interweaved log lines.">;
436438
def log_verbose : Option<"verbose", "v">, Group<1>,

lldb/source/Core/Debugger.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ void Debugger::ReportError(std::string message,
14091409
bool Debugger::EnableLog(llvm::StringRef channel,
14101410
llvm::ArrayRef<const char *> categories,
14111411
llvm::StringRef log_file, uint32_t log_options,
1412-
llvm::raw_ostream &error_stream) {
1412+
size_t buffer_size, llvm::raw_ostream &error_stream) {
14131413
const bool should_close = true;
14141414

14151415
std::shared_ptr<LogHandler> log_handler_sp;
@@ -1420,7 +1420,7 @@ bool Debugger::EnableLog(llvm::StringRef channel,
14201420
LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
14211421
} else if (log_file.empty()) {
14221422
log_handler_sp = std::make_shared<StreamLogHandler>(
1423-
GetOutputFile().GetDescriptor(), !should_close);
1423+
GetOutputFile().GetDescriptor(), !should_close, buffer_size);
14241424
} else {
14251425
auto pos = m_stream_handlers.find(log_file);
14261426
if (pos != m_stream_handlers.end())
@@ -1441,7 +1441,7 @@ bool Debugger::EnableLog(llvm::StringRef channel,
14411441
}
14421442

14431443
log_handler_sp = std::make_shared<StreamLogHandler>(
1444-
(*file)->GetDescriptor(), should_close);
1444+
(*file)->GetDescriptor(), should_close, buffer_size);
14451445
m_stream_handlers[log_file] = log_handler_sp;
14461446
}
14471447
}

lldb/source/Utility/Log.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,14 +339,19 @@ void LogHandler::EmitThreadSafe(llvm::StringRef message) {
339339
Emit(message);
340340
}
341341

342-
StreamLogHandler::StreamLogHandler(int fd, bool should_close, bool unbuffered)
343-
: m_stream(fd, should_close, unbuffered) {}
344-
345-
void StreamLogHandler::Emit(llvm::StringRef message) {
346-
m_stream << message;
347-
m_stream.flush();
342+
StreamLogHandler::StreamLogHandler(int fd, bool should_close,
343+
size_t buffer_size)
344+
: m_stream(fd, should_close, buffer_size == 0) {
345+
if (buffer_size > 0)
346+
m_stream.SetBufferSize(buffer_size);
348347
}
349348

349+
StreamLogHandler::~StreamLogHandler() { Flush(); }
350+
351+
void StreamLogHandler::Flush() { m_stream.flush(); }
352+
353+
void StreamLogHandler::Emit(llvm::StringRef message) { m_stream << message; }
354+
350355
CallbackLogHandler::CallbackLogHandler(lldb::LogOutputCallback callback,
351356
void *baton)
352357
: m_callback(callback), m_baton(baton) {}

lldb/tools/lldb-test/lldb-test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ int main(int argc, const char *argv[]) {
11201120
/*add_to_history*/ eLazyBoolNo, Result);
11211121

11221122
if (!opts::Log.empty())
1123-
Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, errs());
1123+
Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, 0, errs());
11241124

11251125
if (opts::BreakpointSubcommand)
11261126
return opts::breakpoint::evaluateBreakpoints(*Dbg);

0 commit comments

Comments
 (0)