Index: lldb/source/API/SBHostOS.cpp =================================================================== --- lldb/source/API/SBHostOS.cpp +++ lldb/source/API/SBHostOS.cpp @@ -6,10 +6,6 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_DISABLE_PYTHON -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" -#endif - #include "SBReproducerPrivate.h" #include "lldb/API/SBError.h" #include "lldb/API/SBHostOS.h" Index: lldb/source/API/SystemInitializerFull.cpp =================================================================== --- lldb/source/API/SystemInitializerFull.cpp +++ lldb/source/API/SystemInitializerFull.cpp @@ -6,10 +6,6 @@ // //===----------------------------------------------------------------------===// -#if !defined(LLDB_DISABLE_PYTHON) -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" -#endif - #include "SystemInitializerFull.h" #include "lldb/API/SBCommandInterpreter.h" Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -19,16 +19,23 @@ #include #include -#include "PythonDataObjects.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/IOHandler.h" #include "lldb/Host/Terminal.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/lldb-private.h" +// Python forward declarations +struct _ts; +typedef _ts PyThreadState; + class IOHandlerPythonInterpreter; namespace lldb_private { +class PythonScriptInterpreterLocker; +class PythonFile; +class PythonObject; +class PythonDictionary; class ScriptInterpreterPython : public ScriptInterpreter, public IOHandlerDelegateMultiline { @@ -41,6 +48,7 @@ }; friend class ::IOHandlerPythonInterpreter; + friend class lldb_private::PythonScriptInterpreterLocker; ScriptInterpreterPython(CommandInterpreter &interpreter); @@ -324,46 +332,6 @@ uint32_t GetPluginVersion() override; - class Locker : public ScriptInterpreterLocker { - public: - enum OnEntry { - AcquireLock = 0x0001, - InitSession = 0x0002, - InitGlobals = 0x0004, - NoSTDIN = 0x0008 - }; - - enum OnLeave { - FreeLock = 0x0001, - FreeAcquiredLock = 0x0002, // do not free the lock if we already held it - // when calling constructor - TearDownSession = 0x0004 - }; - - Locker(ScriptInterpreterPython *py_interpreter = nullptr, - uint16_t on_entry = AcquireLock | InitSession, - uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr, - FILE *out = nullptr, FILE *err = nullptr); - - ~Locker() override; - - private: - bool DoAcquireLock(); - - bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); - - bool DoFreeLock(); - - bool DoTearDownSession(); - - static void ReleasePythonLock(); - - bool m_teardown_session; - ScriptInterpreterPython *m_python_interpreter; - // FILE* m_tmp_fh; - PyGILState_STATE m_GILState; - }; - protected: static void InitializePrivate(); @@ -422,15 +390,16 @@ bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file, const char *mode); - PythonFile m_saved_stdin; - PythonFile m_saved_stdout; - PythonFile m_saved_stderr; - PythonObject m_main_module; - PythonObject m_lldb_module; - PythonDictionary m_session_dict; - PythonDictionary m_sys_module_dict; - PythonObject m_run_one_line_function; - PythonObject m_run_one_line_str_global; + // Unique pointers so the corresponding class can be forward declared. + std::unique_ptr m_saved_stdin; + std::unique_ptr m_saved_stdout; + std::unique_ptr m_saved_stderr; + std::unique_ptr m_main_module; + std::unique_ptr m_lldb_module; + std::unique_ptr m_session_dict; + std::unique_ptr m_sys_module_dict; + std::unique_ptr m_run_one_line_function; + std::unique_ptr m_run_one_line_str_global; std::string m_dictionary_name; TerminalState m_terminal_state; ActiveIOHandler m_active_io_handler; Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -193,6 +193,111 @@ static bool g_initialized = false; +namespace lldb_private { +class PythonScriptInterpreterLocker : public ScriptInterpreterLocker { +public: + enum OnEntry { + AcquireLock = 0x0001, + InitSession = 0x0002, + InitGlobals = 0x0004, + NoSTDIN = 0x0008 + }; + + enum OnLeave { + FreeLock = 0x0001, + FreeAcquiredLock = 0x0002, // do not free the lock if we already held it + // when calling constructor + TearDownSession = 0x0004 + }; + + PythonScriptInterpreterLocker( + ScriptInterpreterPython *py_interpreter = nullptr, + uint16_t on_entry = AcquireLock | InitSession, + uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr, + FILE *out = nullptr, FILE *err = nullptr); + + ~PythonScriptInterpreterLocker() override; + +private: + bool DoAcquireLock(); + + bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); + + bool DoFreeLock(); + + bool DoTearDownSession(); + + static void ReleasePythonLock(); + + bool m_teardown_session; + ScriptInterpreterPython *m_python_interpreter; + // FILE* m_tmp_fh; + PyGILState_STATE m_GILState; +}; + +PythonScriptInterpreterLocker::PythonScriptInterpreterLocker( + ScriptInterpreterPython *py_interpreter, uint16_t on_entry, + uint16_t on_leave, FILE *in, FILE *out, FILE *err) + : ScriptInterpreterLocker(), + m_teardown_session((on_leave & TearDownSession) == TearDownSession), + m_python_interpreter(py_interpreter) { + DoAcquireLock(); + if ((on_entry & InitSession) == InitSession) { + if (!DoInitSession(on_entry, in, out, err)) { + // Don't teardown the session if we didn't init it. + m_teardown_session = false; + } + } +} + +bool PythonScriptInterpreterLocker::DoAcquireLock() { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + m_GILState = PyGILState_Ensure(); + LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked", + m_GILState == PyGILState_UNLOCKED ? "un" : ""); + + // we need to save the thread state when we first start the command because + // we might decide to interrupt it while some action is taking place outside + // of Python (e.g. printing to screen, waiting for the network, ...) in that + // case, _PyThreadState_Current will be NULL - and we would be unable to set + // the asynchronous exception - not a desirable situation + m_python_interpreter->SetThreadState(PyThreadState_Get()); + m_python_interpreter->IncrementLockCount(); + return true; +} + +bool PythonScriptInterpreterLocker::DoInitSession(uint16_t on_entry_flags, + FILE *in, FILE *out, + FILE *err) { + if (!m_python_interpreter) + return false; + return m_python_interpreter->EnterSession(on_entry_flags, in, out, err); +} + +bool PythonScriptInterpreterLocker::DoFreeLock() { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", + m_GILState == PyGILState_UNLOCKED ? "un" : ""); + PyGILState_Release(m_GILState); + m_python_interpreter->DecrementLockCount(); + return true; +} + +bool PythonScriptInterpreterLocker::DoTearDownSession() { + if (!m_python_interpreter) + return false; + m_python_interpreter->LeaveSession(); + return true; +} + +PythonScriptInterpreterLocker::~PythonScriptInterpreterLocker() { + if (m_teardown_session) + DoTearDownSession(); + DoFreeLock(); +} + +} // namespace lldb_private + namespace { // Initializing Python is not a straightforward process. We cannot control @@ -296,75 +401,20 @@ }; } -ScriptInterpreterPython::Locker::Locker(ScriptInterpreterPython *py_interpreter, - uint16_t on_entry, uint16_t on_leave, - FILE *in, FILE *out, FILE *err) - : ScriptInterpreterLocker(), - m_teardown_session((on_leave & TearDownSession) == TearDownSession), - m_python_interpreter(py_interpreter) { - DoAcquireLock(); - if ((on_entry & InitSession) == InitSession) { - if (!DoInitSession(on_entry, in, out, err)) { - // Don't teardown the session if we didn't init it. - m_teardown_session = false; - } - } -} - -bool ScriptInterpreterPython::Locker::DoAcquireLock() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); - m_GILState = PyGILState_Ensure(); - LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked", - m_GILState == PyGILState_UNLOCKED ? "un" : ""); - - // we need to save the thread state when we first start the command because - // we might decide to interrupt it while some action is taking place outside - // of Python (e.g. printing to screen, waiting for the network, ...) in that - // case, _PyThreadState_Current will be NULL - and we would be unable to set - // the asynchronous exception - not a desirable situation - m_python_interpreter->SetThreadState(PyThreadState_Get()); - m_python_interpreter->IncrementLockCount(); - return true; -} - -bool ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags, - FILE *in, FILE *out, - FILE *err) { - if (!m_python_interpreter) - return false; - return m_python_interpreter->EnterSession(on_entry_flags, in, out, err); -} - -bool ScriptInterpreterPython::Locker::DoFreeLock() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); - LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", - m_GILState == PyGILState_UNLOCKED ? "un" : ""); - PyGILState_Release(m_GILState); - m_python_interpreter->DecrementLockCount(); - return true; -} - -bool ScriptInterpreterPython::Locker::DoTearDownSession() { - if (!m_python_interpreter) - return false; - m_python_interpreter->LeaveSession(); - return true; -} - -ScriptInterpreterPython::Locker::~Locker() { - if (m_teardown_session) - DoTearDownSession(); - DoFreeLock(); -} - ScriptInterpreterPython::ScriptInterpreterPython( CommandInterpreter &interpreter) : ScriptInterpreter(interpreter, eScriptLanguagePython), - IOHandlerDelegateMultiline("DONE"), m_saved_stdin(), m_saved_stdout(), - m_saved_stderr(), m_main_module(), m_lldb_module(), - m_session_dict(PyInitialValue::Invalid), - m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(), - m_run_one_line_str_global(), + IOHandlerDelegateMultiline("DONE"), + m_saved_stdin(llvm::make_unique()), + m_saved_stdout(llvm::make_unique()), + m_saved_stderr(llvm::make_unique()), + m_main_module(llvm::make_unique()), + m_session_dict( + llvm::make_unique(PyInitialValue::Invalid)), + m_sys_module_dict( + llvm::make_unique(PyInitialValue::Invalid)), + m_run_one_line_function(llvm::make_unique()), + m_run_one_line_str_global(llvm::make_unique()), m_dictionary_name( interpreter.GetDebugger().GetInstanceName().AsCString()), m_terminal_state(), m_active_io_handler(eIOHandlerNone), @@ -376,8 +426,9 @@ StreamString run_string; run_string.Printf("%s = dict()", m_dictionary_name.c_str()); - Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock, - ScriptInterpreterPython::Locker::FreeAcquiredLock); + PythonScriptInterpreterLocker locker( + this, PythonScriptInterpreterLocker::AcquireLock, + PythonScriptInterpreterLocker::FreeAcquiredLock); PyRun_SimpleString(run_string.GetData()); run_string.Clear(); @@ -425,7 +476,7 @@ // thread state, nuke the session dictionary and then release it for others // to use and proceed with the rest of the shutdown auto gil_state = PyGILState_Ensure(); - m_session_dict.Reset(); + m_session_dict->Reset(); PyGILState_Release(gil_state); } @@ -650,17 +701,17 @@ if (PyThreadState_GetDict()) { PythonDictionary &sys_module_dict = GetSysModuleDictionary(); if (sys_module_dict.IsValid()) { - if (m_saved_stdin.IsValid()) { - sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin); - m_saved_stdin.Reset(); + if (m_saved_stdin->IsValid()) { + sys_module_dict.SetItemForKey(PythonString("stdin"), *m_saved_stdin); + m_saved_stdin->Reset(); } - if (m_saved_stdout.IsValid()) { - sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout); - m_saved_stdout.Reset(); + if (m_saved_stdout->IsValid()) { + sys_module_dict.SetItemForKey(PythonString("stdout"), *m_saved_stdout); + m_saved_stdout->Reset(); } - if (m_saved_stderr.IsValid()) { - sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr); - m_saved_stderr.Reset(); + if (m_saved_stderr->IsValid()) { + sys_module_dict.SetItemForKey(PythonString("stderr"), *m_saved_stderr); + m_saved_stderr->Reset(); } } } @@ -711,7 +762,7 @@ StreamString run_string; - if (on_entry_flags & Locker::InitGlobals) { + if (on_entry_flags & PythonScriptInterpreterLocker::InitGlobals) { run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID()); @@ -751,23 +802,23 @@ m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid(in_sp, out_sp, err_sp); - if (on_entry_flags & Locker::NoSTDIN) { - m_saved_stdin.Reset(); + if (on_entry_flags & PythonScriptInterpreterLocker::NoSTDIN) { + m_saved_stdin->Reset(); } else { - if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r")) { + if (!SetStdHandle(in_file, "stdin", *m_saved_stdin, "r")) { if (in_sp) - SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r"); + SetStdHandle(in_sp->GetFile(), "stdin", *m_saved_stdin, "r"); } } - if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w")) { + if (!SetStdHandle(out_file, "stdout", *m_saved_stdout, "w")) { if (out_sp) - SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w"); + SetStdHandle(out_sp->GetFile(), "stdout", *m_saved_stdout, "w"); } - if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w")) { + if (!SetStdHandle(err_file, "stderr", *m_saved_stderr, "w")) { if (err_sp) - SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w"); + SetStdHandle(err_sp->GetFile(), "stderr", *m_saved_stderr, "w"); } } @@ -778,38 +829,38 @@ } PythonObject &ScriptInterpreterPython::GetMainModule() { - if (!m_main_module.IsValid()) - m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__")); - return m_main_module; + if (!m_main_module->IsValid()) + m_main_module->Reset(PyRefType::Borrowed, PyImport_AddModule("__main__")); + return *m_main_module; } PythonDictionary &ScriptInterpreterPython::GetSessionDictionary() { - if (m_session_dict.IsValid()) - return m_session_dict; + if (m_session_dict->IsValid()) + return *m_session_dict; PythonObject &main_module = GetMainModule(); if (!main_module.IsValid()) - return m_session_dict; + return *m_session_dict; PythonDictionary main_dict(PyRefType::Borrowed, PyModule_GetDict(main_module.get())); if (!main_dict.IsValid()) - return m_session_dict; + return *m_session_dict; PythonObject item = main_dict.GetItemForKey(PythonString(m_dictionary_name)); - m_session_dict.Reset(PyRefType::Borrowed, item.get()); - return m_session_dict; + m_session_dict->Reset(PyRefType::Borrowed, item.get()); + return *m_session_dict; } PythonDictionary &ScriptInterpreterPython::GetSysModuleDictionary() { - if (m_sys_module_dict.IsValid()) - return m_sys_module_dict; + if (m_sys_module_dict->IsValid()) + return *m_sys_module_dict; PythonObject sys_module(PyRefType::Borrowed, PyImport_AddModule("sys")); if (sys_module.IsValid()) - m_sys_module_dict.Reset(PyRefType::Borrowed, - PyModule_GetDict(sys_module.get())); - return m_sys_module_dict; + m_sys_module_dict->Reset(PyRefType::Borrowed, + PyModule_GetDict(sys_module.get())); + return *m_sys_module_dict; } static std::string GenerateUniqueName(const char *base_name_wanted, @@ -829,7 +880,7 @@ } bool ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects() { - if (m_run_one_line_function.IsValid()) + if (m_run_one_line_function->IsValid()) return true; PythonObject module(PyRefType::Borrowed, @@ -842,11 +893,11 @@ if (!module_dict.IsValid()) return false; - m_run_one_line_function = + *m_run_one_line_function = module_dict.GetItemForKey(PythonString("run_one_line")); - m_run_one_line_str_global = + *m_run_one_line_str_global = module_dict.GetItemForKey(PythonString("g_run_one_line_str")); - return m_run_one_line_function.IsValid(); + return m_run_one_line_function->IsValid(); } static void ReadThreadBytesReceived(void *baton, const void *src, @@ -950,30 +1001,32 @@ // below will redirect Python's stdio to use this same handle. If we // close the handle while Python is still using it, bad things will // happen. - Locker locker( + PythonScriptInterpreterLocker locker( this, - ScriptInterpreterPython::Locker::AcquireLock | - ScriptInterpreterPython::Locker::InitSession | + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | (options.GetSetLLDBGlobals() - ? ScriptInterpreterPython::Locker::InitGlobals + ? PythonScriptInterpreterLocker::InitGlobals : 0) | - ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN), - ScriptInterpreterPython::Locker::FreeAcquiredLock | - ScriptInterpreterPython::Locker::TearDownSession, + ((result && result->GetInteractive()) + ? 0 + : PythonScriptInterpreterLocker::NoSTDIN), + PythonScriptInterpreterLocker::FreeAcquiredLock | + PythonScriptInterpreterLocker::TearDownSession, in_file, out_file, err_file); // Find the correct script interpreter dictionary in the main module. PythonDictionary &session_dict = GetSessionDictionary(); if (session_dict.IsValid()) { if (GetEmbeddedInterpreterModuleObjects()) { - if (PyCallable_Check(m_run_one_line_function.get())) { + if (PyCallable_Check(m_run_one_line_function->get())) { PythonObject pargs( PyRefType::Owned, Py_BuildValue("(Os)", session_dict.get(), command_str.c_str())); if (pargs.IsValid()) { PythonObject return_value( PyRefType::Owned, - PyObject_CallObject(m_run_one_line_function.get(), + PyObject_CallObject(m_run_one_line_function->get(), pargs.get())); if (return_value.IsValid()) success = true; @@ -1049,12 +1102,13 @@ terminal.SetEcho(true); } - ScriptInterpreterPython::Locker locker( - m_python, ScriptInterpreterPython::Locker::AcquireLock | - ScriptInterpreterPython::Locker::InitSession | - ScriptInterpreterPython::Locker::InitGlobals, - ScriptInterpreterPython::Locker::FreeAcquiredLock | - ScriptInterpreterPython::Locker::TearDownSession); + PythonScriptInterpreterLocker locker( + m_python, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::InitGlobals, + PythonScriptInterpreterLocker::FreeAcquiredLock | + PythonScriptInterpreterLocker::TearDownSession); // The following call drops into the embedded interpreter loop and // stays there until the user chooses to exit from the Python @@ -1139,14 +1193,16 @@ llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options) { - Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock | - ScriptInterpreterPython::Locker::InitSession | - (options.GetSetLLDBGlobals() - ? ScriptInterpreterPython::Locker::InitGlobals - : 0) | - Locker::NoSTDIN, - ScriptInterpreterPython::Locker::FreeAcquiredLock | - ScriptInterpreterPython::Locker::TearDownSession); + PythonScriptInterpreterLocker locker( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + (options.GetSetLLDBGlobals() + ? PythonScriptInterpreterLocker::InitGlobals + : 0) | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeAcquiredLock | + PythonScriptInterpreterLocker::TearDownSession); PythonObject py_return; PythonObject &main_module = GetMainModule(); @@ -1295,14 +1351,16 @@ const char *in_string, const ExecuteScriptOptions &options) { Status error; - Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock | - ScriptInterpreterPython::Locker::InitSession | - (options.GetSetLLDBGlobals() - ? ScriptInterpreterPython::Locker::InitGlobals - : 0) | - Locker::NoSTDIN, - ScriptInterpreterPython::Locker::FreeAcquiredLock | - ScriptInterpreterPython::Locker::TearDownSession); + PythonScriptInterpreterLocker locker( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + (options.GetSetLLDBGlobals() + ? PythonScriptInterpreterLocker::InitGlobals + : 0) | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeAcquiredLock | + PythonScriptInterpreterLocker::TearDownSession); PythonObject return_value; PythonObject &main_module = GetMainModule(); @@ -1611,8 +1669,11 @@ void *ret_val; { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); ret_val = LLDBSWIGPython_CreateFrameRecognizer(class_name, m_dictionary_name.c_str()); } @@ -1623,7 +1684,11 @@ lldb::ValueObjectListSP ScriptInterpreterPython::GetRecognizedArguments( const StructuredData::ObjectSP &os_plugin_object_sp, lldb::StackFrameSP frame_sp) { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); if (!os_plugin_object_sp) return ValueObjectListSP(); @@ -1670,8 +1735,11 @@ void *ret_val; { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); ret_val = LLDBSWIGPythonCreateOSPlugin( class_name, m_dictionary_name.c_str(), process_sp); } @@ -1681,7 +1749,11 @@ StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_RegisterInfo( StructuredData::ObjectSP os_plugin_object_sp) { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "get_register_info"; @@ -1736,7 +1808,11 @@ StructuredData::ArraySP ScriptInterpreterPython::OSPlugin_ThreadsInfo( StructuredData::ObjectSP os_plugin_object_sp) { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "get_thread_info"; @@ -1821,7 +1897,11 @@ StructuredData::StringSP ScriptInterpreterPython::OSPlugin_RegisterContextData( StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "get_register_data"; static char *param_format = @@ -1878,7 +1958,11 @@ StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_CreateThread( StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context) { - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "create_thread"; std::string param_format; @@ -1954,8 +2038,10 @@ void *ret_val; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPythonCreateScriptedThreadPlan( class_name, python_interpreter->m_dictionary_name.c_str(), @@ -1972,8 +2058,10 @@ if (implementor_sp) generic = implementor_sp->GetAsGeneric(); if (generic) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); explains_stop = LLDBSWIGPythonCallThreadPlan( generic->GetValue(), "explains_stop", event, script_error); if (script_error) @@ -1989,8 +2077,10 @@ if (implementor_sp) generic = implementor_sp->GetAsGeneric(); if (generic) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); should_stop = LLDBSWIGPythonCallThreadPlan( generic->GetValue(), "should_stop", event, script_error); if (script_error) @@ -2006,8 +2096,10 @@ if (implementor_sp) generic = implementor_sp->GetAsGeneric(); if (generic) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); is_stale = LLDBSWIGPythonCallThreadPlan(generic->GetValue(), "is_stale", nullptr, script_error); if (script_error) @@ -2023,8 +2115,10 @@ if (implementor_sp) generic = implementor_sp->GetAsGeneric(); if (generic) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); should_step = LLDBSWIGPythonCallThreadPlan( generic->GetValue(), "should_step", NULL, script_error); if (script_error) @@ -2060,8 +2154,10 @@ void *ret_val; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPythonCreateScriptedBreakpointResolver( class_name, python_interpreter->m_dictionary_name.c_str(), args_data, @@ -2078,8 +2174,10 @@ bool should_continue = false; if (implementor_sp) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); should_continue = LLDBSwigPythonCallBreakpointResolver( implementor_sp->GetValue(), "__callback__", sym_ctx); if (PyErr_Occurred()) { @@ -2095,8 +2193,10 @@ StructuredData::GenericSP implementor_sp) { int depth_as_int = lldb::eSearchDepthModule; if (implementor_sp) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); depth_as_int = LLDBSwigPythonCallBreakpointResolver( implementor_sp->GetValue(), "__get_depth__", nullptr); if (PyErr_Occurred()) { @@ -2140,8 +2240,10 @@ return StructuredData::DictionarySP(); PythonObject reply_pyobj; - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); TargetSP target_sp(target->shared_from_this()); reply_pyobj.Reset(PyRefType::Owned, (PyObject *)LLDBSWIGPython_GetDynamicSetting( @@ -2178,8 +2280,10 @@ void *ret_val = nullptr; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPythonCreateSyntheticProvider( class_name, python_interpreter->m_dictionary_name.c_str(), valobj); } @@ -2201,8 +2305,10 @@ void *ret_val; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPythonCreateCommandObject( class_name, m_dictionary_name.c_str(), debugger_sp); } @@ -2297,8 +2403,10 @@ bool ret_val; if (python_function_name && *python_function_name) { { - Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | - Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); { TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options)); @@ -2323,8 +2431,9 @@ void ScriptInterpreterPython::Clear() { // Release any global variables that might have strong references to // LLDB objects when clearing the python script interpreter. - Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock, - ScriptInterpreterPython::Locker::FreeAcquiredLock); + PythonScriptInterpreterLocker locker( + this, PythonScriptInterpreterLocker::AcquireLock, + PythonScriptInterpreterLocker::FreeAcquiredLock); // This may be called as part of Py_Finalize. In that case the modules are // destroyed in random order and we can't guarantee that we can access these. @@ -2367,9 +2476,11 @@ if (stop_frame_sp && bp_loc_sp) { bool ret_val = true; { - Locker py_lock(python_interpreter, Locker::AcquireLock | - Locker::InitSession | - Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + python_interpreter, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPythonBreakpointCallbackFunction( python_function_name, python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, @@ -2415,9 +2526,11 @@ if (stop_frame_sp && wp_sp) { bool ret_val = true; { - Locker py_lock(python_interpreter, Locker::AcquireLock | - Locker::InitSession | - Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + python_interpreter, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPythonWatchpointCallbackFunction( python_function_name, python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, @@ -2446,8 +2559,10 @@ size_t ret_val = 0; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPython_CalculateNumChildren(implementor, max); } @@ -2469,8 +2584,10 @@ lldb::ValueObjectSP ret_val; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); void *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx); if (child_ptr != nullptr && child_ptr != Py_None) { lldb::SBValue *sb_value_ptr = @@ -2502,8 +2619,10 @@ int ret_val = UINT32_MAX; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPython_GetIndexOfChildWithName(implementor, child_name); } @@ -2525,8 +2644,10 @@ return ret_val; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPython_UpdateSynthProviderInstance(implementor); } @@ -2549,8 +2670,10 @@ { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSwigPython_MightHaveChildrenSynthProviderInstance(implementor); } @@ -2573,8 +2696,10 @@ return ret_val; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); void *child_ptr = LLDBSwigPython_GetValueSynthProviderInstance(implementor); if (child_ptr != nullptr && child_ptr != Py_None) { lldb::SBValue *sb_value_ptr = @@ -2593,8 +2718,10 @@ ConstString ScriptInterpreterPython::GetSyntheticTypeName( const StructuredData::ObjectSP &implementor_sp) { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); static char callee_name[] = "get_type_name"; @@ -2673,8 +2800,10 @@ { ProcessSP process_sp(process->shared_from_this()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSWIGPythonRunScriptKeywordProcess( impl_function, m_dictionary_name.c_str(), process_sp, output); if (!ret_val) @@ -2699,8 +2828,10 @@ { ThreadSP thread_sp(thread->shared_from_this()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSWIGPythonRunScriptKeywordThread( impl_function, m_dictionary_name.c_str(), thread_sp, output); if (!ret_val) @@ -2725,8 +2856,10 @@ { TargetSP target_sp(target->shared_from_this()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSWIGPythonRunScriptKeywordTarget( impl_function, m_dictionary_name.c_str(), target_sp, output); if (!ret_val) @@ -2751,8 +2884,10 @@ { StackFrameSP frame_sp(frame->shared_from_this()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSWIGPythonRunScriptKeywordFrame( impl_function, m_dictionary_name.c_str(), frame_sp, output); if (!ret_val) @@ -2777,8 +2912,10 @@ { ValueObjectSP value_sp(value->GetSP()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonScriptInterpreterLocker py_lock( + this, PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN); ret_val = LLDBSWIGPythonRunScriptKeywordValue( impl_function, m_dictionary_name.c_str(), value_sp, output); if (!ret_val) @@ -2817,11 +2954,14 @@ StreamString command_stream; // Before executing Python code, lock the GIL. - Locker py_lock(this, Locker::AcquireLock | - (init_session ? Locker::InitSession : 0) | - Locker::NoSTDIN, - Locker::FreeAcquiredLock | - (init_session ? Locker::TearDownSession : 0)); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + (init_session ? PythonScriptInterpreterLocker::InitSession : 0) | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeAcquiredLock | + (init_session ? PythonScriptInterpreterLocker::TearDownSession + : 0)); namespace fs = llvm::sys::fs; fs::file_status st; std::error_code ec = status(target_file.GetPath(), st); @@ -3012,10 +3152,15 @@ std::string err_msg; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | - (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), - Locker::FreeLock | Locker::TearDownSession); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + (cmd_retobj.GetInteractive() + ? 0 + : PythonScriptInterpreterLocker::NoSTDIN), + PythonScriptInterpreterLocker::FreeLock | + PythonScriptInterpreterLocker::TearDownSession); SynchronicityHandler synch_handler(debugger_sp, synchronicity); @@ -3056,10 +3201,15 @@ std::string err_msg; { - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | - (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), - Locker::FreeLock | Locker::TearDownSession); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + (cmd_retobj.GetInteractive() + ? 0 + : PythonScriptInterpreterLocker::NoSTDIN), + PythonScriptInterpreterLocker::FreeLock | + PythonScriptInterpreterLocker::TearDownSession); SynchronicityHandler synch_handler(debugger_sp, synchronicity); @@ -3112,7 +3262,11 @@ bool got_string = false; dest.clear(); - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "get_short_help"; @@ -3167,7 +3321,11 @@ StructuredData::GenericSP cmd_obj_sp) { uint32_t result = 0; - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "get_flags"; @@ -3222,7 +3380,11 @@ bool got_string = false; dest.clear(); - Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + PythonScriptInterpreterLocker py_lock( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock); static char callee_name[] = "get_long_help"; @@ -3277,9 +3439,14 @@ std::unique_ptr ScriptInterpreterPython::AcquireInterpreterLock() { - std::unique_ptr py_lock(new Locker( - this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN, - Locker::FreeLock | Locker::TearDownSession)); + std::unique_ptr py_lock( + new PythonScriptInterpreterLocker( + this, + PythonScriptInterpreterLocker::AcquireLock | + PythonScriptInterpreterLocker::InitSession | + PythonScriptInterpreterLocker::NoSTDIN, + PythonScriptInterpreterLocker::FreeLock | + PythonScriptInterpreterLocker::TearDownSession)); return py_lock; } Index: lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h +++ lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h @@ -32,6 +32,12 @@ #undef _XOPEN_SOURCE #endif +// Include locale before Python so _PY_PORT_CTYPE_UTF8_ISSUE doesn't cause +// macro redefinitions. +#if defined(__APPLE__) +#include +#endif + // Include python for non windows machines #include #endif // LLDB_DISABLE_PYTHON