Skip to content

Commit 70841b9

Browse files
committed
[lldb] Make thread safety the responsibility of the log handlers
Drop the thread-safe flag and make the locking strategy the responsibility of the individual log handler. Previously we got away with a non-thread safe mode because we were using unbuffered streams that rely on the underlying syscalls/OS for synchronization. With the introduction of log handlers, we can have arbitrary logic involved in writing out the logs. With this patch the log handlers can pick the most appropriate locking strategy for their particular implementation. Differential revision: https://reviews.llvm.org/D127922
1 parent 09dea54 commit 70841b9

File tree

7 files changed

+23
-31
lines changed

7 files changed

+23
-31
lines changed

lldb/include/lldb/Utility/Log.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ namespace llvm {
3333
class raw_ostream;
3434
}
3535
// Logging Options
36-
#define LLDB_LOG_OPTION_THREADSAFE (1u << 0)
3736
#define LLDB_LOG_OPTION_VERBOSE (1u << 1)
3837
#define LLDB_LOG_OPTION_PREPEND_SEQUENCE (1u << 3)
3938
#define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4)
@@ -50,10 +49,6 @@ class LogHandler {
5049
public:
5150
virtual ~LogHandler() = default;
5251
virtual void Emit(llvm::StringRef message) = 0;
53-
void EmitThreadSafe(llvm::StringRef message);
54-
55-
private:
56-
std::mutex m_mutex;
5752
};
5853

5954
class StreamLogHandler : public LogHandler {
@@ -65,6 +60,7 @@ class StreamLogHandler : public LogHandler {
6560
void Flush();
6661

6762
private:
63+
std::mutex m_mutex;
6864
llvm::raw_fd_ostream m_stream;
6965
};
7066

@@ -91,6 +87,7 @@ class RotatingLogHandler : public LogHandler {
9187
size_t GetNumMessages() const;
9288
size_t GetFirstMessageIndex() const;
9389

90+
mutable std::mutex m_mutex;
9491
std::unique_ptr<std::string[]> m_messages;
9592
const size_t m_size = 0;
9693
size_t m_next_index = 0;

lldb/source/Commands/CommandObjectLog.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ class CommandObjectLogEnable : public CommandObjectParsed {
9494
error =
9595
buffer_size.SetValueFromString(option_arg, eVarSetOperationAssign);
9696
break;
97-
case 't':
98-
log_options |= LLDB_LOG_OPTION_THREADSAFE;
99-
break;
10097
case 'v':
10198
log_options |= LLDB_LOG_OPTION_VERBOSE;
10299
break;

lldb/source/Commands/Options.td

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,6 @@ let Command = "log enable" in {
433433
Desc<"Set the destination file to log to.">;
434434
def log_buffer_size : Option<"buffer", "b">, Group<1>, Arg<"UnsignedInteger">,
435435
Desc<"Set the log to be buffered, using the specified buffer size.">;
436-
def log_threadsafe : Option<"threadsafe", "t">, Group<1>,
437-
Desc<"Enable thread safe logging to avoid interweaved log lines.">;
438436
def log_verbose : Option<"verbose", "v">, Group<1>,
439437
Desc<"Enable verbose logging.">;
440438
def log_sequence : Option<"sequence", "s">, Group<1>,

lldb/source/Core/Debugger.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,8 +1448,7 @@ bool Debugger::EnableLog(llvm::StringRef channel,
14481448
assert(log_handler_sp);
14491449

14501450
if (log_options == 0)
1451-
log_options =
1452-
LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1451+
log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
14531452

14541453
return Log::EnableLogChannel(log_handler_sp, log_options, channel, categories,
14551454
error_stream);

lldb/source/Utility/Log.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,7 @@ void Log::WriteMessage(const std::string &message) {
317317
auto handler_sp = GetHandler();
318318
if (!handler_sp)
319319
return;
320-
321-
Flags options = GetOptions();
322-
if (options.Test(LLDB_LOG_OPTION_THREADSAFE))
323-
handler_sp->EmitThreadSafe(message);
324-
else
325-
handler_sp->Emit(message);
320+
handler_sp->Emit(message);
326321
}
327322

328323
void Log::Format(llvm::StringRef file, llvm::StringRef function,
@@ -334,11 +329,6 @@ void Log::Format(llvm::StringRef file, llvm::StringRef function,
334329
WriteMessage(message.str());
335330
}
336331

337-
void LogHandler::EmitThreadSafe(llvm::StringRef message) {
338-
std::lock_guard<std::mutex> guard(m_mutex);
339-
Emit(message);
340-
}
341-
342332
StreamLogHandler::StreamLogHandler(int fd, bool should_close,
343333
size_t buffer_size)
344334
: m_stream(fd, should_close, buffer_size == 0) {
@@ -348,9 +338,19 @@ StreamLogHandler::StreamLogHandler(int fd, bool should_close,
348338

349339
StreamLogHandler::~StreamLogHandler() { Flush(); }
350340

351-
void StreamLogHandler::Flush() { m_stream.flush(); }
341+
void StreamLogHandler::Flush() {
342+
std::lock_guard<std::mutex> guard(m_mutex);
343+
m_stream.flush();
344+
}
352345

353-
void StreamLogHandler::Emit(llvm::StringRef message) { m_stream << message; }
346+
void StreamLogHandler::Emit(llvm::StringRef message) {
347+
if (m_stream.GetBufferSize() > 0) {
348+
std::lock_guard<std::mutex> guard(m_mutex);
349+
m_stream << message;
350+
} else {
351+
m_stream << message;
352+
}
353+
}
354354

355355
CallbackLogHandler::CallbackLogHandler(lldb::LogOutputCallback callback,
356356
void *baton)
@@ -364,6 +364,7 @@ RotatingLogHandler::RotatingLogHandler(size_t size)
364364
: m_messages(std::make_unique<std::string[]>(size)), m_size(size) {}
365365

366366
void RotatingLogHandler::Emit(llvm::StringRef message) {
367+
std::lock_guard<std::mutex> guard(m_mutex);
367368
++m_total_count;
368369
const size_t index = m_next_index;
369370
m_next_index = NormalizeIndex(index + 1);
@@ -381,6 +382,7 @@ size_t RotatingLogHandler::GetFirstMessageIndex() const {
381382
}
382383

383384
void RotatingLogHandler::Dump(llvm::raw_ostream &stream) const {
385+
std::lock_guard<std::mutex> guard(m_mutex);
384386
const size_t start_idx = GetFirstMessageIndex();
385387
const size_t stop_idx = start_idx + GetNumMessages();
386388
for (size_t i = start_idx; i < stop_idx; ++i) {

lldb/test/API/commands/log/basic/TestLogging.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def test_file_writing(self):
3131
# By default, Debugger::EnableLog() will set log options to
3232
# PREPEND_THREAD_NAME + OPTION_THREADSAFE. We don't want the
3333
# threadnames here, so we enable just threadsafe (-t).
34-
self.runCmd("log enable -t -f '%s' lldb commands" % (self.log_file))
34+
self.runCmd("log enable -f '%s' lldb commands" % (self.log_file))
3535

3636
self.runCmd("command alias bp breakpoint")
3737

@@ -59,7 +59,7 @@ def test_log_truncate(self):
5959
for i in range(1, 1000):
6060
f.write("bacon\n")
6161

62-
self.runCmd("log enable -t -f '%s' lldb commands" % self.log_file)
62+
self.runCmd("log enable -f '%s' lldb commands" % self.log_file)
6363
self.runCmd("help log")
6464
self.runCmd("log disable lldb")
6565

@@ -76,7 +76,7 @@ def test_log_append(self):
7676
with open(self.log_file, "w") as f:
7777
f.write("bacon\n")
7878

79-
self.runCmd( "log enable -t -a -f '%s' lldb commands" % self.log_file)
79+
self.runCmd( "log enable -a -f '%s' lldb commands" % self.log_file)
8080
self.runCmd("help log")
8181
self.runCmd("log disable lldb")
8282

@@ -93,7 +93,7 @@ def test_all_log_options(self):
9393
if (os.path.exists(self.log_file)):
9494
os.remove(self.log_file)
9595

96-
self.runCmd("log enable -v -t -s -T -p -n -S -F -f '%s' lldb commands" % self.log_file)
96+
self.runCmd("log enable -v -s -T -p -n -S -F -f '%s' lldb commands" % self.log_file)
9797
self.runCmd("help log")
9898
self.runCmd("log disable lldb")
9999

lldb/unittests/Utility/LogTest.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,7 @@ TEST_F(LogChannelTest, List) {
270270
TEST_F(LogChannelEnabledTest, log_options) {
271271
std::string Err;
272272
EXPECT_EQ("Hello World\n", logAndTakeOutput("Hello World"));
273-
EXPECT_TRUE(EnableChannel(getLogHandler(), LLDB_LOG_OPTION_THREADSAFE, "chan",
274-
{}, Err));
273+
EXPECT_TRUE(EnableChannel(getLogHandler(), 0, "chan", {}, Err));
275274
EXPECT_EQ("Hello World\n", logAndTakeOutput("Hello World"));
276275

277276
{

0 commit comments

Comments
 (0)