Author: Jonas Devlieghere Date: 2022-01-19T09:56:55-08:00 New Revision: eb5c0ea681803361a1944c966f4becaa9e22dc1a
URL: https://github.com/llvm/llvm-project/commit/eb5c0ea681803361a1944c966f4becaa9e22dc1a DIFF: https://github.com/llvm/llvm-project/commit/eb5c0ea681803361a1944c966f4becaa9e22dc1a.diff LOG: [lldb] Initialize Python exactly once We got a few crash reports that showed LLDB initializing Python on two separate threads. Make sure Python is initialized exactly once. rdar://87287005 Differential revision: https://reviews.llvm.org/D117601 Added: Modified: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 0e01dc52b2513..80e986f18c618 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -85,8 +85,6 @@ static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) { return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter); } -static bool g_initialized = false; - namespace { // Initializing Python is not a straightforward process. We cannot control @@ -219,6 +217,28 @@ struct InitializePythonRAII { PyGILState_STATE m_gil_state = PyGILState_UNLOCKED; bool m_was_already_initialized = false; }; + +#if LLDB_USE_PYTHON_SET_INTERRUPT +/// Saves the current signal handler for the specified signal and restores +/// it at the end of the current scope. +struct RestoreSignalHandlerScope { + /// The signal handler. + struct sigaction m_prev_handler; + int m_signal_code; + RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) { + // Initialize sigaction to their default state. + std::memset(&m_prev_handler, 0, sizeof(m_prev_handler)); + // Don't install a new handler, just read back the old one. + struct sigaction *new_handler = nullptr; + int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler); + lldbassert(signal_err == 0 && "sigaction failed to read handler"); + } + ~RestoreSignalHandlerScope() { + int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr); + lldbassert(signal_err == 0 && "sigaction failed to restore old handler"); + } +}; +#endif } // namespace void ScriptInterpreterPython::ComputePythonDirForApple( @@ -333,12 +353,12 @@ llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() { void ScriptInterpreterPython::Initialize() { static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), lldb::eScriptLanguagePython, ScriptInterpreterPythonImpl::CreateInstance); + ScriptInterpreterPythonImpl::Initialize(); }); } @@ -415,8 +435,6 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) m_active_io_handler(eIOHandlerNone), m_session_is_active(false), m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0), m_command_thread_state(nullptr) { - InitializePrivate(); - m_scripted_process_interface_up = std::make_unique<ScriptedProcessPythonInterface>(*this); @@ -3151,36 +3169,7 @@ ScriptInterpreterPythonImpl::AcquireInterpreterLock() { return py_lock; } -#if LLDB_USE_PYTHON_SET_INTERRUPT -namespace { -/// Saves the current signal handler for the specified signal and restores -/// it at the end of the current scope. -struct RestoreSignalHandlerScope { - /// The signal handler. - struct sigaction m_prev_handler; - int m_signal_code; - RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) { - // Initialize sigaction to their default state. - std::memset(&m_prev_handler, 0, sizeof(m_prev_handler)); - // Don't install a new handler, just read back the old one. - struct sigaction *new_handler = nullptr; - int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler); - lldbassert(signal_err == 0 && "sigaction failed to read handler"); - } - ~RestoreSignalHandlerScope() { - int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr); - lldbassert(signal_err == 0 && "sigaction failed to restore old handler"); - } -}; -} // namespace -#endif - -void ScriptInterpreterPythonImpl::InitializePrivate() { - if (g_initialized) - return; - - g_initialized = true; - +void ScriptInterpreterPythonImpl::Initialize() { LLDB_SCOPED_TIMER(); // RAII-based initialization which correctly handles multiple-initialization, diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index defc2acffcfa9..3b80c67d201ad 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -341,7 +341,7 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id); - static void InitializePrivate(); + static void Initialize(); class SynchronicityHandler { private: diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index ba96cc67a68fe..a0e97a29f2e13 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -22,7 +22,6 @@ using namespace lldb_private; class TestScriptInterpreterPython : public ScriptInterpreterPythonImpl { public: using ScriptInterpreterPythonImpl::Initialize; - using ScriptInterpreterPythonImpl::InitializePrivate; }; void PythonTestSuite::SetUp() { @@ -31,7 +30,6 @@ void PythonTestSuite::SetUp() { // ScriptInterpreterPython::Initialize() depends on HostInfo being // initializedso it can compute the python directory etc. TestScriptInterpreterPython::Initialize(); - TestScriptInterpreterPython::InitializePrivate(); // Although we don't care about concurrency for the purposes of running // this test suite, Python requires the GIL to be locked even for _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits