Skip to content

Commit fc849bd

Browse files
committed
[lldb] add plugin names to process save-core error output.
show the plugin names in when running `help plugin save-core`
1 parent fe28ea3 commit fc849bd

File tree

6 files changed

+69
-10
lines changed

6 files changed

+69
-10
lines changed

lldb/include/lldb/Core/PluginManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ class PluginManager {
270270
static Status SaveCore(const lldb::ProcessSP &process_sp,
271271
lldb_private::SaveCoreOptions &core_options);
272272

273+
static std::vector<llvm::StringRef> GetSaveCorePluginNames();
274+
273275
// ObjectContainer
274276
static bool RegisterPlugin(
275277
llvm::StringRef name, llvm::StringRef description,

lldb/source/Commands/CommandObjectProcess.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,27 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed {
12811281
~CommandOptions() override = default;
12821282

12831283
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1284-
return llvm::ArrayRef(g_process_save_core_options);
1284+
if (!m_opt_def.empty())
1285+
return llvm::ArrayRef(m_opt_def);
1286+
1287+
auto orig = llvm::ArrayRef(g_process_save_core_options);
1288+
m_opt_def.resize(orig.size());
1289+
llvm::copy(g_process_save_core_options, m_opt_def.data());
1290+
for (OptionDefinition &value : m_opt_def) {
1291+
llvm::StringRef opt_name = value.long_option;
1292+
if (opt_name != "plugin-name")
1293+
continue;
1294+
1295+
std::vector<llvm::StringRef> plugin_names =
1296+
PluginManager::GetSaveCorePluginNames();
1297+
m_plugin_enums.resize(plugin_names.size());
1298+
for (auto [num, val] : llvm::zip(plugin_names, m_plugin_enums)) {
1299+
val.string_value = num.data();
1300+
}
1301+
value.enum_values = llvm::ArrayRef(m_plugin_enums);
1302+
break;
1303+
}
1304+
return llvm::ArrayRef(m_opt_def);
12851305
}
12861306

12871307
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1312,6 +1332,8 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed {
13121332

13131333
// Instance variables to hold the values for command options.
13141334
SaveCoreOptions m_core_dump_options;
1335+
llvm::SmallVector<OptionEnumValueElement> m_plugin_enums;
1336+
std::vector<OptionDefinition> m_opt_def;
13151337
};
13161338

13171339
protected:

lldb/source/Core/PluginManager.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -843,11 +843,28 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
843843
}
844844

845845
// Check to see if any of the object file plugins tried and failed to save.
846-
// If none ran, set the error message.
847-
if (error.Success())
848-
error = Status::FromErrorString(
849-
"no ObjectFile plugins were able to save a core for this process");
850-
return error;
846+
// if any failure, return the error message.
847+
if (error.Fail())
848+
return error;
849+
850+
// Report only for the plugin that was specified.
851+
if (!plugin_name.empty())
852+
return Status::FromErrorStringWithFormatv(
853+
"The \"{}\" plugin is not able to save a core for this process.",
854+
plugin_name);
855+
856+
return Status::FromErrorString(
857+
"no ObjectFile plugins were able to save a core for this process");
858+
}
859+
860+
std::vector<llvm::StringRef> PluginManager::GetSaveCorePluginNames() {
861+
std::vector<llvm::StringRef> plugin_names;
862+
auto instances = GetObjectFileInstances().GetSnapshot();
863+
for (auto &instance : instances) {
864+
if (instance.save_core)
865+
plugin_names.emplace_back(instance.name);
866+
}
867+
return plugin_names;
851868
}
852869

853870
#pragma mark ObjectContainer

lldb/source/Symbol/SaveCoreOptions.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,20 @@ Status SaveCoreOptions::SetPluginName(const char *name) {
2121
return error;
2222
}
2323

24-
if (!PluginManager::IsRegisteredObjectFilePluginName(name)) {
25-
return Status::FromErrorStringWithFormat(
26-
"plugin name '%s' is not a valid ObjectFile plugin name", name);
24+
std::vector<llvm::StringRef> plugin_names =
25+
PluginManager::GetSaveCorePluginNames();
26+
if (llvm::find(plugin_names, name) == plugin_names.end()) {
27+
StreamString stream;
28+
stream.Printf("plugin name '%s' is not a valid ObjectFile plugin name.",
29+
name);
30+
31+
if (!plugin_names.empty()) {
32+
stream.PutCString(" Valid names are: ");
33+
std::string plugin_names_str = llvm::join(plugin_names, ", ");
34+
stream.PutCString(plugin_names_str);
35+
stream.PutChar('.');
36+
}
37+
return Status(stream.GetString().str());
2738
}
2839

2940
m_plugin_name = name;

lldb/test/API/functionalities/process_save_core/TestProcessSaveCore.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,10 @@ def test_save_core_via_process_plugin(self):
8888
os.unlink(core)
8989
except OSError:
9090
pass
91+
92+
def test_help(self):
93+
"""Test that help shows minidump as an option in plugin-names."""
94+
self.expect(
95+
"help process save-core",
96+
substrs=["process save-core", "<plugin>", "Values:", "minidump"],
97+
)

lldb/test/Shell/Commands/command-process-save-core-not-a-plugin.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ run
1616

1717
process save-core --plugin-name=notaplugin dump
1818
# CHECK-LABEL: process save-core --plugin-name=notaplugin dump
19-
# CHECK: error: plugin name 'notaplugin' is not a valid ObjectFile plugin name
19+
# CHECK: error: plugin name 'notaplugin' is not a valid ObjectFile plugin name. Valid names are:{{.*}}minidump{{.*}}

0 commit comments

Comments
 (0)