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

continuation of
[#142684](https://github.com/llvm/llvm-project/pull/142684) to show
plugin names.

From issue [#14258](https://github.com/llvm/llvm-project/issues/142581)
This commit is contained in:
Ebuka Ezike 2025-06-23 18:02:58 +01:00 committed by GitHub
parent 1bc63265af
commit 8d83d04637
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 86 additions and 11 deletions

View File

@ -264,6 +264,8 @@ public:
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,

View File

@ -1281,7 +1281,27 @@ public:
~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 @@ public:
// 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:

View File

@ -989,11 +989,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

View File

@ -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;

View File

@ -88,3 +88,21 @@ class ProcessSaveCoreTestCase(TestBase):
os.unlink(core)
except OSError:
pass
def test_help(self):
"""Test that help shows an option in plugin-names and style."""
self.expect(
"help process save-core",
substrs=["process save-core", "<plugin>", "Values:", "minidump"],
)
self.expect(
"help process save-core",
substrs=[
"process save-core",
"<corefile-style>",
"Values:",
"full",
"stack",
],
)

View File

@ -2,7 +2,7 @@
# with a plugin that does not exist.
# RUN: %clang_host -g %S/Inputs/main.c -o %t
# RUN: %lldb %t -s %s -o exit 2>&1 | FileCheck %s
# RUN: %lldb %t -o "settings set interpreter.stop-command-source-on-error false" -s %s -o exit 2>&1 | FileCheck %s
b main
# CHECK-LABEL: b main
@ -14,6 +14,11 @@ run
# CHECK: stop reason = breakpoint 1
# CHECK: frame #0: {{.*}}`main at main.c
process save-core --plugin-name=minidump
# CHECK-LABEL: process save-core --plugin-name=minidump
# CHECK: error: 'process save-core' takes one arguments:
# CHECK: Usage: {{.*}} FILE
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{{.*}}