diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2021-07-09 09:23:54 -0700 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2021-07-09 10:05:39 -0700 |
commit | f9517353959b4ef5c706e4356b56aeb9e0087584 (patch) | |
tree | 5960dcb4a254fe27fcd73f78c2aca32efd83464a /lldb/source/Plugins | |
parent | 0ac7532cc17aebf1b93d95142c5edec7e66ebad0 (diff) | |
download | llvm-f9517353959b4ef5c706e4356b56aeb9e0087584.zip llvm-f9517353959b4ef5c706e4356b56aeb9e0087584.tar.gz llvm-f9517353959b4ef5c706e4356b56aeb9e0087584.tar.bz2 |
[lldb] Add the ability to silently import scripted commands
Add the ability to silence command script import. The motivation for
this change is being able to add command script import -s
lldb.macosx.crashlog to your ~/.lldbinit without it printing the
following message at the beginning of every debug session.
"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and
"objc_refs" commands have been installed, use the "--help" options on
these commands for detailed help.
In addition to forwarding the silent option to LoadScriptingModule, this
also changes ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn and
ScriptInterpreterPythonImpl::ExecuteMultipleLines to honor the enable IO
option in ExecuteScriptOptions, which until now was ignored.
Note that IO is only enabled (or disabled) at the start of a session,
and for this particular use case, that's done when taking the Python
lock in LoadScriptingModule, which means that the changes to these two
functions are not strictly necessary, but (IMO) desirable nonetheless.
Differential revision: https://reviews.llvm.org/D105327
Diffstat (limited to 'lldb/source/Plugins')
5 files changed, 75 insertions, 36 deletions
diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index a117ce0..730c88f 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -91,13 +91,13 @@ OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process, std::string os_plugin_class_name( python_module_path.GetFilename().AsCString("")); if (!os_plugin_class_name.empty()) { - const bool init_session = false; + LoadScriptOptions options; char python_module_path_cstr[PATH_MAX]; python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr)); Status error; - if (m_interpreter->LoadScriptingModule(python_module_path_cstr, - init_session, error)) { + if (m_interpreter->LoadScriptingModule(python_module_path_cstr, options, + error)) { // Strip the ".py" extension if there is one size_t py_extension_pos = os_plugin_class_name.rfind(".py"); if (py_extension_pos != std::string::npos) diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp index 2105f4a..ef46401 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -207,8 +207,9 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() { } bool ScriptInterpreterLua::LoadScriptingModule( - const char *filename, bool init_session, lldb_private::Status &error, - StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) { + const char *filename, const LoadScriptOptions &options, + lldb_private::Status &error, StructuredData::ObjectSP *module_sp, + FileSpec extra_search_dir) { FileSystem::Instance().Collect(filename); if (llvm::Error e = m_lua->LoadModule(filename)) { diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h index 5eeac56..808000b 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h @@ -43,7 +43,8 @@ public: void ExecuteInterpreterLoop() override; - bool LoadScriptingModule(const char *filename, bool init_session, + bool LoadScriptingModule(const char *filename, + const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}) override; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 86549b0..7ad6372 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1077,11 +1077,24 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn( llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options) { + llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + options.GetEnableIO(), m_debugger, /*result=*/nullptr); + + if (!io_redirect_or_error) { + llvm::consumeError(io_redirect_or_error.takeError()); + return false; + } + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; + Locker locker(this, Locker::AcquireLock | Locker::InitSession | (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | Locker::NoSTDIN, - Locker::FreeAcquiredLock | Locker::TearDownSession); + Locker::FreeAcquiredLock | Locker::TearDownSession, + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); PythonModule &main_module = GetMainModule(); PythonDictionary globals = main_module.GetDictionary(); @@ -1190,11 +1203,22 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines( if (in_string == nullptr) return Status(); + llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + options.GetEnableIO(), m_debugger, /*result=*/nullptr); + + if (!io_redirect_or_error) + return Status(io_redirect_or_error.takeError()); + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; + Locker locker(this, Locker::AcquireLock | Locker::InitSession | (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | Locker::NoSTDIN, - Locker::FreeAcquiredLock | Locker::TearDownSession); + Locker::FreeAcquiredLock | Locker::TearDownSession, + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); PythonModule &main_module = GetMainModule(); PythonDictionary globals = main_module.GetDictionary(); @@ -2057,7 +2081,10 @@ ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec, StructuredData::ObjectSP module_sp; - if (LoadScriptingModule(file_spec.GetPath().c_str(), true, error, &module_sp)) + LoadScriptOptions load_script_options = + LoadScriptOptions().SetInitSession(true).SetSilent(false); + if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options, + error, &module_sp)) return module_sp; return StructuredData::ObjectSP(); @@ -2732,26 +2759,44 @@ uint64_t replace_all(std::string &str, const std::string &oldStr, } bool ScriptInterpreterPythonImpl::LoadScriptingModule( - const char *pathname, bool init_session, lldb_private::Status &error, - StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) { + const char *pathname, const LoadScriptOptions &options, + lldb_private::Status &error, StructuredData::ObjectSP *module_sp, + FileSpec extra_search_dir) { namespace fs = llvm::sys::fs; namespace path = llvm::sys::path; + ExecuteScriptOptions exc_options = ExecuteScriptOptions() + .SetEnableIO(!options.GetSilent()) + .SetSetLLDBGlobals(false); + if (!pathname || !pathname[0]) { error.SetErrorString("invalid pathname"); return false; } + llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr); + + if (!io_redirect_or_error) { + error = io_redirect_or_error.takeError(); + return false; + } + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); // Before executing Python code, lock the GIL. Locker py_lock(this, Locker::AcquireLock | - (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN, + (options.GetInitSession() ? Locker::InitSession : 0) | + Locker::NoSTDIN, Locker::FreeAcquiredLock | - (init_session ? Locker::TearDownSession : 0)); + (options.GetInitSession() ? Locker::TearDownSession : 0), + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); - auto ExtendSysPath = [this](std::string directory) -> llvm::Error { + auto ExtendSysPath = [&](std::string directory) -> llvm::Error { if (directory.empty()) { return llvm::make_error<llvm::StringError>( "invalid directory name", llvm::inconvertibleErrorCode()); @@ -2766,11 +2811,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( "sys.path.insert(1,'%s');\n\n", directory.c_str(), directory.c_str()); bool syspath_retval = - ExecuteMultipleLines(command_stream.GetData(), - ExecuteScriptOptions() - .SetEnableIO(false) - .SetSetLLDBGlobals(false)) - .Success(); + ExecuteMultipleLines(command_stream.GetData(), exc_options).Success(); if (!syspath_retval) { return llvm::make_error<llvm::StringError>( "Python sys.path handling failed", llvm::inconvertibleErrorCode()); @@ -2844,21 +2885,18 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( return false; } - // check if the module is already import-ed + // Check if the module is already imported. StreamString command_stream; command_stream.Clear(); command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str()); bool does_contain = false; - // this call will succeed if the module was ever imported in any Debugger - // in the lifetime of the process in which this LLDB framework is living - const bool was_imported_globally = - (ExecuteOneLineWithReturn( - command_stream.GetData(), - ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, - ExecuteScriptOptions() - .SetEnableIO(false) - .SetSetLLDBGlobals(false)) && - does_contain); + // This call will succeed if the module was ever imported in any Debugger in + // the lifetime of the process in which this LLDB framework is living. + const bool does_contain_executed = ExecuteOneLineWithReturn( + command_stream.GetData(), + ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options); + + const bool was_imported_globally = does_contain_executed && does_contain; const bool was_imported_locally = GetSessionDictionary() .GetItemForKey(PythonString(module_name)) @@ -2876,10 +2914,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( } else command_stream.Printf("import %s", module_name.c_str()); - error = ExecuteMultipleLines(command_stream.GetData(), - ExecuteScriptOptions() - .SetEnableIO(false) - .SetSetLLDBGlobals(false)); + error = ExecuteMultipleLines(command_stream.GetData(), exc_options); if (error.Fail()) return false; @@ -2898,7 +2933,8 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( void *module_pyobj = nullptr; if (ExecuteOneLineWithReturn( command_stream.GetData(), - ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) && + ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj, + exc_options) && module_pyobj) *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj); } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index e0056f1..d1b0b3f 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -234,7 +234,8 @@ public: bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, std::string &output, Status &error) override; - bool LoadScriptingModule(const char *filename, bool init_session, + bool LoadScriptingModule(const char *filename, + const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}) override; |