Skip to content

Commit 8d83d04

Browse files
authored
[lldb] add plugin names to process save-core error output. (#143126)
continuation of [#142684](#142684) to show plugin names. From issue [#14258](#142581)
1 parent 1bc6326 commit 8d83d04

File tree

6 files changed

+86
-11
lines changed

6 files changed

+86
-11
lines changed

lldb/include/lldb/Core/PluginManager.h

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

267+
static std::vector<llvm::StringRef> GetSaveCorePluginNames();
268+
267269
// ObjectContainer
268270
static bool RegisterPlugin(
269271
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
@@ -989,11 +989,28 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
989989
}
990990

991991
// Check to see if any of the object file plugins tried and failed to save.
992-
// If none ran, set the error message.
993-
if (error.Success())
994-
error = Status::FromErrorString(
995-
"no ObjectFile plugins were able to save a core for this process");
996-
return error;
992+
// if any failure, return the error message.
993+
if (error.Fail())
994+
return error;
995+
996+
// Report only for the plugin that was specified.
997+
if (!plugin_name.empty())
998+
return Status::FromErrorStringWithFormatv(
999+
"The \"{}\" plugin is not able to save a core for this process.",
1000+
plugin_name);
1001+
1002+
return Status::FromErrorString(
1003+
"no ObjectFile plugins were able to save a core for this process");
1004+
}
1005+
1006+
std::vector<llvm::StringRef> PluginManager::GetSaveCorePluginNames() {
1007+
std::vector<llvm::StringRef> plugin_names;
1008+
auto instances = GetObjectFileInstances().GetSnapshot();
1009+
for (auto &instance : instances) {
1010+
if (instance.save_core)
1011+
plugin_names.emplace_back(instance.name);
1012+
}
1013+
return plugin_names;
9971014
}
9981015

9991016
#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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,21 @@ 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 an option in plugin-names and style."""
94+
self.expect(
95+
"help process save-core",
96+
substrs=["process save-core", "<plugin>", "Values:", "minidump"],
97+
)
98+
99+
self.expect(
100+
"help process save-core",
101+
substrs=[
102+
"process save-core",
103+
"<corefile-style>",
104+
"Values:",
105+
"full",
106+
"stack",
107+
],
108+
)

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# with a plugin that does not exist.
33

44
# RUN: %clang_host -g %S/Inputs/main.c -o %t
5-
# RUN: %lldb %t -s %s -o exit 2>&1 | FileCheck %s
5+
# RUN: %lldb %t -o "settings set interpreter.stop-command-source-on-error false" -s %s -o exit 2>&1 | FileCheck %s
66

77
b main
88
# CHECK-LABEL: b main
@@ -14,6 +14,11 @@ run
1414
# CHECK: stop reason = breakpoint 1
1515
# CHECK: frame #0: {{.*}}`main at main.c
1616

17+
process save-core --plugin-name=minidump
18+
# CHECK-LABEL: process save-core --plugin-name=minidump
19+
# CHECK: error: 'process save-core' takes one arguments:
20+
# CHECK: Usage: {{.*}} FILE
21+
1722
process save-core --plugin-name=notaplugin dump
1823
# CHECK-LABEL: process save-core --plugin-name=notaplugin dump
19-
# CHECK: error: plugin name 'notaplugin' is not a valid ObjectFile plugin name
24+
# CHECK: error: plugin name 'notaplugin' is not a valid ObjectFile plugin name. Valid names are:{{.*}}minidump{{.*}}

0 commit comments

Comments
 (0)