JDevlieghere created this revision.
JDevlieghere added reviewers: teemperor, jingham, clayborg.
Herald added a subscriber: dang.
JDevlieghere requested review of this revision.

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 ```"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.``` at the beginning 
of every debug session.

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.


https://reviews.llvm.org/D105327

Files:
  lldb/include/lldb/Interpreter/ScriptInterpreter.h
  lldb/source/Commands/CommandObjectCommands.cpp
  lldb/source/Commands/Options.td
  lldb/source/Core/Module.cpp
  lldb/source/Interpreter/ScriptInterpreter.cpp
  lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
  lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
  lldb/test/Shell/ScriptInterpreter/Python/silent_command_script_import.test

Index: lldb/test/Shell/ScriptInterpreter/Python/silent_command_script_import.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Python/silent_command_script_import.test
@@ -0,0 +1,8 @@
+# REQUIRES: python
+
+# RUN: %lldb --script-language python -o 'command script import lldb.macosx.crashlog' 2>&1 | FileCheck %s
+# RUN: %lldb --script-language python -o 'command script import -s lldb.macosx.crashlog' 2>&1 | FileCheck %s --check-prefix SILENT
+# RUN: %lldb --script-language python -o 'command script import --silent lldb.macosx.crashlog' 2>&1 | FileCheck %s --check-prefix SILENT
+
+CHECK: commands have been installed
+SILENT-NOT: commands have been installed
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -234,7 +234,7 @@
   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, bool init_session, bool silent,
                            lldb_private::Status &error,
                            StructuredData::ObjectSP *module_sp = nullptr,
                            FileSpec extra_search_dir = {}) override;
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1077,11 +1077,24 @@
     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, 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,23 @@
   if (in_string == nullptr)
     return Status();
 
+  llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+      io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+          options.GetEnableIO(), m_debugger, 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 +2082,10 @@
 
   StructuredData::ObjectSP module_sp;
 
-  if (LoadScriptingModule(file_spec.GetPath().c_str(), true, error, &module_sp))
+  const bool init_session = true;
+  const bool silent = false;
+  if (LoadScriptingModule(file_spec.GetPath().c_str(), init_session, silent,
+                          error, &module_sp))
     return module_sp;
 
   return StructuredData::ObjectSP();
@@ -2732,16 +2760,31 @@
 }
 
 bool ScriptInterpreterPythonImpl::LoadScriptingModule(
-    const char *pathname, bool init_session, lldb_private::Status &error,
-    StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+    const char *pathname, bool init_session, bool silent,
+    lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
+    FileSpec extra_search_dir) {
   namespace fs = llvm::sys::fs;
   namespace path = llvm::sys::path;
 
+  ExecuteScriptOptions options = ScriptInterpreter::ExecuteScriptOptions()
+                                     .SetEnableIO(!silent)
+                                     .SetSetLLDBGlobals(false);
+
   if (!pathname || !pathname[0]) {
     error.SetErrorString("invalid pathname");
     return false;
   }
 
+  llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+      io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+          options.GetEnableIO(), m_debugger, 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.
@@ -2749,9 +2792,11 @@
                  Locker::AcquireLock |
                      (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN,
                  Locker::FreeAcquiredLock |
-                     (init_session ? Locker::TearDownSession : 0));
+                     (init_session ? 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 @@
                           "sys.path.insert(1,'%s');\n\n",
                           directory.c_str(), directory.c_str());
     bool syspath_retval =
-        ExecuteMultipleLines(command_stream.GetData(),
-                             ScriptInterpreter::ExecuteScriptOptions()
-                                 .SetEnableIO(false)
-                                 .SetSetLLDBGlobals(false))
-            .Success();
+        ExecuteMultipleLines(command_stream.GetData(), options).Success();
     if (!syspath_retval) {
       return llvm::make_error<llvm::StringError>(
           "Python sys.path handling failed", llvm::inconvertibleErrorCode());
@@ -2855,9 +2896,7 @@
       (ExecuteOneLineWithReturn(
            command_stream.GetData(),
            ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
-           ScriptInterpreter::ExecuteScriptOptions()
-               .SetEnableIO(false)
-               .SetSetLLDBGlobals(false)) &&
+           options) &&
        does_contain);
   const bool was_imported_locally =
       GetSessionDictionary()
@@ -2876,10 +2915,7 @@
   } else
     command_stream.Printf("import %s", module_name.c_str());
 
-  error = ExecuteMultipleLines(command_stream.GetData(),
-                               ScriptInterpreter::ExecuteScriptOptions()
-                                   .SetEnableIO(false)
-                                   .SetSetLLDBGlobals(false));
+  error = ExecuteMultipleLines(command_stream.GetData(), options);
   if (error.Fail())
     return false;
 
@@ -2898,7 +2934,8 @@
     void *module_pyobj = nullptr;
     if (ExecuteOneLineWithReturn(
             command_stream.GetData(),
-            ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) &&
+            ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj,
+            options) &&
         module_pyobj)
       *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
   }
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -42,7 +42,7 @@
 
   void ExecuteInterpreterLoop() override;
 
-  bool LoadScriptingModule(const char *filename, bool init_session,
+  bool LoadScriptingModule(const char *filename, bool init_session, bool silent,
                            lldb_private::Status &error,
                            StructuredData::ObjectSP *module_sp = nullptr,
                            FileSpec extra_search_dir = {}) override;
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -195,8 +195,9 @@
 }
 
 bool ScriptInterpreterLua::LoadScriptingModule(
-    const char *filename, bool init_session, lldb_private::Status &error,
-    StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+    const char *filename, bool init_session, bool silent,
+    lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
+    FileSpec extra_search_dir) {
 
   FileSystem::Instance().Collect(filename);
   if (llvm::Error e = m_lua->LoadModule(filename)) {
Index: lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
===================================================================
--- lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -92,12 +92,13 @@
         python_module_path.GetFilename().AsCString(""));
     if (!os_plugin_class_name.empty()) {
       const bool init_session = false;
+      const bool silent = false;
       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)) {
+                                             init_session, silent, 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)
Index: lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/ScriptInterpreter.cpp
+++ lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -47,7 +47,7 @@
 }
 
 bool ScriptInterpreter::LoadScriptingModule(const char *filename,
-                                            bool init_session,
+                                            bool init_session, bool silent,
                                             lldb_private::Status &error,
                                             StructuredData::ObjectSP *module_sp,
                                             FileSpec extra_search_dir) {
Index: lldb/source/Core/Module.cpp
===================================================================
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -1529,8 +1529,9 @@
             StreamString scripting_stream;
             scripting_fspec.Dump(scripting_stream.AsRawOstream());
             const bool init_lldb_globals = false;
+            const bool silent = false;
             bool did_load = script_interpreter->LoadScriptingModule(
-                scripting_stream.GetData(), init_lldb_globals, error);
+                scripting_stream.GetData(), init_lldb_globals, silent, error);
             if (!did_load)
               return false;
           }
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -745,6 +745,8 @@
     Group<1>, Desc<"Resolve non-absolute paths relative to the location of the "
     "current command file. This argument can only be used when the command is "
     "being sourced from a file.">;
+  def silent : Option<"silent", "s">, Group<1>,
+    Desc<"If true don't print output while importing.">;
 }
 
 let Command = "script add" in {
Index: lldb/source/Commands/CommandObjectCommands.cpp
===================================================================
--- lldb/source/Commands/CommandObjectCommands.cpp
+++ lldb/source/Commands/CommandObjectCommands.cpp
@@ -1242,6 +1242,9 @@
       case 'c':
         relative_to_command_file = true;
         break;
+      case 's':
+        silent = true;
+        break;
       default:
         llvm_unreachable("Unimplemented option");
       }
@@ -1257,6 +1260,7 @@
       return llvm::makeArrayRef(g_script_import_options);
     }
     bool relative_to_command_file = false;
+    bool silent = false;
   };
 
   bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -1279,6 +1283,7 @@
       Status error;
 
       const bool init_session = true;
+      const bool silent = m_options.silent;
       // FIXME: this is necessary because CommandObject::CheckRequirements()
       // assumes that commands won't ever be recursively invoked, but it's
       // actually possible to craft a Python script that does other "command
@@ -1289,7 +1294,8 @@
       // more)
       m_exe_ctx.Clear();
       if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
-              entry.c_str(), init_session, error, nullptr, source_dir)) {
+              entry.c_str(), init_session, silent, error, nullptr,
+              source_dir)) {
         result.SetStatus(eReturnStatusSuccessFinishNoResult);
       } else {
         result.AppendErrorWithFormat("module importing failed: %s",
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -509,7 +509,7 @@
   virtual bool CheckObjectExists(const char *name) { return false; }
 
   virtual bool
-  LoadScriptingModule(const char *filename, bool init_session,
+  LoadScriptingModule(const char *filename, bool init_session, bool silent,
                       lldb_private::Status &error,
                       StructuredData::ObjectSP *module_sp = nullptr,
                       FileSpec extra_search_dir = {});
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to