[Lldb-commits] [lldb] [lldb] add plugin names to process save-core error output. (PR #143126)

Ebuka Ezike via lldb-commits lldb-commits at lists.llvm.org
Sun Jun 15 02:50:13 PDT 2025


https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/143126

>From fc849bd4e831f9dc6f53be3a8508e1eb33f4151c Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Fri, 6 Jun 2025 13:15:41 +0100
Subject: [PATCH] [lldb] add plugin names to process save-core error output.

show the plugin names in when running `help plugin save-core`
---
 lldb/include/lldb/Core/PluginManager.h        |  2 ++
 lldb/source/Commands/CommandObjectProcess.cpp | 24 ++++++++++++++++-
 lldb/source/Core/PluginManager.cpp            | 27 +++++++++++++++----
 lldb/source/Symbol/SaveCoreOptions.cpp        | 17 +++++++++---
 .../process_save_core/TestProcessSaveCore.py  |  7 +++++
 ...ommand-process-save-core-not-a-plugin.test |  2 +-
 6 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
index e7b1691031111..0e917025ba41e 100644
--- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h
@@ -270,6 +270,8 @@ class PluginManager {
   static Status SaveCore(const lldb::ProcessSP &process_sp,
                          lldb_private::SaveCoreOptions &core_options);
 
+  static std::vector<llvm::StringRef> GetSaveCorePluginNames();
+
   // ObjectContainer
   static bool RegisterPlugin(
       llvm::StringRef name, llvm::StringRef description,
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index b1f243c9e2777..0a1744277d7dc 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1281,7 +1281,27 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed {
     ~CommandOptions() override = default;
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
-      return llvm::ArrayRef(g_process_save_core_options);
+      if (!m_opt_def.empty())
+        return llvm::ArrayRef(m_opt_def);
+
+      auto orig = llvm::ArrayRef(g_process_save_core_options);
+      m_opt_def.resize(orig.size());
+      llvm::copy(g_process_save_core_options, m_opt_def.data());
+      for (OptionDefinition &value : m_opt_def) {
+        llvm::StringRef opt_name = value.long_option;
+        if (opt_name != "plugin-name")
+          continue;
+
+        std::vector<llvm::StringRef> plugin_names =
+            PluginManager::GetSaveCorePluginNames();
+        m_plugin_enums.resize(plugin_names.size());
+        for (auto [num, val] : llvm::zip(plugin_names, m_plugin_enums)) {
+          val.string_value = num.data();
+        }
+        value.enum_values = llvm::ArrayRef(m_plugin_enums);
+        break;
+      }
+      return llvm::ArrayRef(m_opt_def);
     }
 
     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1312,6 +1332,8 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed {
 
     // Instance variables to hold the values for command options.
     SaveCoreOptions m_core_dump_options;
+    llvm::SmallVector<OptionEnumValueElement> m_plugin_enums;
+    std::vector<OptionDefinition> m_opt_def;
   };
 
 protected:
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 5d44434033c55..94d66f0f929cd 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -843,11 +843,28 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
   }
 
   // Check to see if any of the object file plugins tried and failed to save.
-  // If none ran, set the error message.
-  if (error.Success())
-    error = Status::FromErrorString(
-        "no ObjectFile plugins were able to save a core for this process");
-  return error;
+  // if any failure, return the error message.
+  if (error.Fail())
+    return error;
+
+  // Report only for the plugin that was specified.
+  if (!plugin_name.empty())
+    return Status::FromErrorStringWithFormatv(
+        "The \"{}\" plugin is not able to save a core for this process.",
+        plugin_name);
+
+  return Status::FromErrorString(
+      "no ObjectFile plugins were able to save a core for this process");
+}
+
+std::vector<llvm::StringRef> PluginManager::GetSaveCorePluginNames() {
+  std::vector<llvm::StringRef> plugin_names;
+  auto instances = GetObjectFileInstances().GetSnapshot();
+  for (auto &instance : instances) {
+    if (instance.save_core)
+      plugin_names.emplace_back(instance.name);
+  }
+  return plugin_names;
 }
 
 #pragma mark ObjectContainer
diff --git a/lldb/source/Symbol/SaveCoreOptions.cpp b/lldb/source/Symbol/SaveCoreOptions.cpp
index d884b00a47b00..0f9dbb73c1721 100644
--- a/lldb/source/Symbol/SaveCoreOptions.cpp
+++ b/lldb/source/Symbol/SaveCoreOptions.cpp
@@ -21,9 +21,20 @@ Status SaveCoreOptions::SetPluginName(const char *name) {
     return error;
   }
 
-  if (!PluginManager::IsRegisteredObjectFilePluginName(name)) {
-    return Status::FromErrorStringWithFormat(
-        "plugin name '%s' is not a valid ObjectFile plugin name", name);
+  std::vector<llvm::StringRef> plugin_names =
+      PluginManager::GetSaveCorePluginNames();
+  if (llvm::find(plugin_names, name) == plugin_names.end()) {
+    StreamString stream;
+    stream.Printf("plugin name '%s' is not a valid ObjectFile plugin name.",
+                  name);
+
+    if (!plugin_names.empty()) {
+      stream.PutCString(" Valid names are: ");
+      std::string plugin_names_str = llvm::join(plugin_names, ", ");
+      stream.PutCString(plugin_names_str);
+      stream.PutChar('.');
+    }
+    return Status(stream.GetString().str());
   }
 
   m_plugin_name = name;
diff --git a/lldb/test/API/functionalities/process_save_core/TestProcessSaveCore.py b/lldb/test/API/functionalities/process_save_core/TestProcessSaveCore.py
index 8573d15733927..4f2b690ade3a9 100644
--- a/lldb/test/API/functionalities/process_save_core/TestProcessSaveCore.py
+++ b/lldb/test/API/functionalities/process_save_core/TestProcessSaveCore.py
@@ -88,3 +88,10 @@ def test_save_core_via_process_plugin(self):
                 os.unlink(core)
             except OSError:
                 pass
+
+    def test_help(self):
+        """Test that help shows minidump as an option in plugin-names."""
+        self.expect(
+            "help process save-core",
+            substrs=["process save-core", "<plugin>", "Values:", "minidump"],
+        )
diff --git a/lldb/test/Shell/Commands/command-process-save-core-not-a-plugin.test b/lldb/test/Shell/Commands/command-process-save-core-not-a-plugin.test
index c034c8ebbf87d..e5a1d9ae40692 100644
--- a/lldb/test/Shell/Commands/command-process-save-core-not-a-plugin.test
+++ b/lldb/test/Shell/Commands/command-process-save-core-not-a-plugin.test
@@ -16,4 +16,4 @@ run
 
 process save-core --plugin-name=notaplugin dump
 # CHECK-LABEL: process save-core --plugin-name=notaplugin dump
-# CHECK: error: plugin name 'notaplugin' is not a valid ObjectFile plugin name
+# CHECK: error: plugin name 'notaplugin' is not a valid ObjectFile plugin name. Valid names are:{{.*}}minidump{{.*}}



More information about the lldb-commits mailing list