[Lldb-commits] [lldb] r316368 - Logging: Disable logging after fork()
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Mon Oct 23 12:41:17 PDT 2017
Author: labath
Date: Mon Oct 23 12:41:17 2017
New Revision: 316368
URL: http://llvm.org/viewvc/llvm-project?rev=316368&view=rev
Log:
Logging: Disable logging after fork()
Summary:
We had a bug where if we had forked (in the ProcessLauncherPosixFork)
while another thread was writing a log message, we would deadlock. This
happened because the fork child inherited the locked log rwmutex, which
would never get unlocked. This meant the child got stuck trying to
disable all log channels.
The bug existed for a while but only started being apparent after
D37930, which started using ThreadLauncher (which uses logging) instead
of std::thread (which does not) for launching TaskPool threads.
The fix is to use pthread_atfork to disable logging in the forked child.
Reviewers: zturner, eugene, clayborg
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D38938
Modified:
lldb/trunk/include/lldb/Utility/Log.h
lldb/trunk/include/lldb/Utility/Logging.h
lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp
lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
lldb/trunk/source/Utility/Log.cpp
lldb/trunk/source/Utility/Logging.cpp
Modified: lldb/trunk/include/lldb/Utility/Log.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Log.h?rev=316368&r1=316367&r2=316368&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/Log.h (original)
+++ lldb/trunk/include/lldb/Utility/Log.h Mon Oct 23 12:41:17 2017
@@ -96,6 +96,9 @@ public:
}
};
+
+ static void Initialize();
+
//------------------------------------------------------------------
// Static accessors for logging channels
//------------------------------------------------------------------
@@ -193,6 +196,8 @@ private:
static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
llvm::ArrayRef<const char *> categories);
+ static void DisableLoggingChild();
+
Log(const Log &) = delete;
void operator=(const Log &) = delete;
};
Modified: lldb/trunk/include/lldb/Utility/Logging.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Logging.h?rev=316368&r1=316367&r2=316368&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/Logging.h (original)
+++ lldb/trunk/include/lldb/Utility/Logging.h Mon Oct 23 12:41:17 2017
@@ -62,7 +62,7 @@ Log *GetLogIfAllCategoriesSet(uint32_t m
Log *GetLogIfAnyCategoriesSet(uint32_t mask);
-void InitializeLog();
+void InitializeLldbChannel();
} // namespace lldb_private
Modified: lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp?rev=316368&r1=316367&r2=316368&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp (original)
+++ lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp Mon Oct 23 12:41:17 2017
@@ -95,10 +95,6 @@ static void DupDescriptor(int error_fd,
static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
const ProcessLaunchInfo &info) {
- // First, make sure we disable all logging. If we are logging to stdout, our
- // logs can be mistaken for inferior output.
- Log::DisableAllLogChannels();
-
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
ExitWithError(error_fd, "setgid");
Modified: lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Initialization/SystemInitializerCommon.cpp?rev=316368&r1=316367&r2=316368&view=diff
==============================================================================
--- lldb/trunk/source/Initialization/SystemInitializerCommon.cpp (original)
+++ lldb/trunk/source/Initialization/SystemInitializerCommon.cpp Mon Oct 23 12:41:17 2017
@@ -70,7 +70,7 @@ void SystemInitializerCommon::Initialize
#endif
llvm::EnablePrettyStackTrace();
- InitializeLog();
+ Log::Initialize();
HostInfo::Initialize();
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
Modified: lldb/trunk/source/Utility/Log.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/Log.cpp?rev=316368&r1=316367&r2=316368&view=diff
==============================================================================
--- lldb/trunk/source/Utility/Log.cpp (original)
+++ lldb/trunk/source/Utility/Log.cpp Mon Oct 23 12:41:17 2017
@@ -32,6 +32,7 @@
#include <process.h> // for getpid
#else
#include <unistd.h>
+#include <pthread.h>
#endif
using namespace lldb_private;
@@ -181,6 +182,13 @@ void Log::Warning(const char *format, ..
Printf("warning: %s", Content.c_str());
}
+void Log::Initialize() {
+#ifdef LLVM_ON_UNIX
+ pthread_atfork(nullptr, nullptr, &Log::DisableLoggingChild);
+#endif
+ InitializeLldbChannel();
+}
+
void Log::Register(llvm::StringRef name, Channel &channel) {
auto iter = g_channel_map->try_emplace(name, channel);
assert(iter.second == true);
@@ -321,3 +329,11 @@ void Log::Format(llvm::StringRef file, l
message << payload << "\n";
WriteMessage(message.str());
}
+
+void Log::DisableLoggingChild() {
+ // Disable logging by clearing out the atomic variable after forking -- if we
+ // forked while another thread held the channel mutex, we would deadlock when
+ // trying to write to the log.
+ for (auto &c: *g_channel_map)
+ c.second.m_channel.log_ptr.store(nullptr, std::memory_order_relaxed);
+}
Modified: lldb/trunk/source/Utility/Logging.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/Logging.cpp?rev=316368&r1=316367&r2=316368&view=diff
==============================================================================
--- lldb/trunk/source/Utility/Logging.cpp (original)
+++ lldb/trunk/source/Utility/Logging.cpp Mon Oct 23 12:41:17 2017
@@ -51,7 +51,7 @@ static constexpr Log::Category g_categor
static Log::Channel g_log_channel(g_categories, LIBLLDB_LOG_DEFAULT);
-void lldb_private::InitializeLog() {
+void lldb_private::InitializeLldbChannel() {
Log::Register("lldb", g_log_channel);
}
More information about the lldb-commits
mailing list