aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectProcess.cpp
diff options
context:
space:
mode:
authorJason Molenda <jason@molenda.com>2021-06-20 12:19:50 -0700
committerJason Molenda <jason@molenda.com>2021-06-20 12:26:54 -0700
commit9ea6dd5cfac0b233fbb148c1e2d0f81f816737c8 (patch)
tree9498050b63f4c736f4f86d9cb3c65734517001d2 /lldb/source/Commands/CommandObjectProcess.cpp
parent1ae266f4529fe17c11331f11db74428b879f3737 (diff)
downloadllvm-9ea6dd5cfac0b233fbb148c1e2d0f81f816737c8.zip
llvm-9ea6dd5cfac0b233fbb148c1e2d0f81f816737c8.tar.gz
llvm-9ea6dd5cfac0b233fbb148c1e2d0f81f816737c8.tar.bz2
Add a corefile style option to process save-core; skinny corefiles
Add a new feature to process save-core on Darwin systems -- for lldb to create a user process corefile with only the dirty (modified memory) pages included. All of the binaries that were used in the corefile are assumed to still exist on the system for the duration of the use of the corefile. A new --style option to process save-core is added, so a full corefile can be requested if portability across systems, or across time, is needed for this corefile. debugserver can now identify the dirty pages in a memory region when queried with qMemoryRegionInfo, and the size of vm pages is given in qHostInfo. Create a new "all image infos" LC_NOTE for Mach-O which allows us to describe all of the binaries that were loaded in the process -- load address, UUID, file path, segment load addresses, and optionally whether code from the binary was executing on any thread. The old "read dyld_all_image_infos and then the in-memory Mach-O load commands to get segment load addresses" no longer works when we only have dirty memory. rdar://69670807 Differential Revision: https://reviews.llvm.org/D88387
Diffstat (limited to 'lldb/source/Commands/CommandObjectProcess.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp71
1 files changed, 69 insertions, 2 deletions
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index ad608a6..a0c5fc9 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1161,26 +1161,91 @@ protected:
// CommandObjectProcessSaveCore
#pragma mark CommandObjectProcessSaveCore
+static constexpr OptionEnumValueElement g_corefile_save_style[] = {
+ {eSaveCoreFull, "full", "Create a core file with all memory saved"},
+ {eSaveCoreDirtyOnly, "modified-memory",
+ "Create a corefile with only modified memory saved"}};
+
+static constexpr OptionEnumValues SaveCoreStyles() {
+ return OptionEnumValues(g_corefile_save_style);
+}
+
+#define LLDB_OPTIONS_process_save_core
+#include "CommandOptions.inc"
+
class CommandObjectProcessSaveCore : public CommandObjectParsed {
public:
CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "process save-core",
"Save the current process as a core file using an "
"appropriate file type.",
- "process save-core FILE",
+ "process save-core [-s corefile-style] FILE",
eCommandRequiresProcess | eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched) {}
~CommandObjectProcessSaveCore() override = default;
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_requested_save_core_style(eSaveCoreUnspecified) {}
+
+ ~CommandOptions() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_save_core_options);
+ }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ const int short_option = m_getopt_table[option_idx].val;
+ Status error;
+
+ switch (short_option) {
+ case 's':
+ m_requested_save_core_style =
+ (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values,
+ eSaveCoreUnspecified, error);
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return {};
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_requested_save_core_style = eSaveCoreUnspecified;
+ }
+
+ // Instance variables to hold the values for command options.
+ SaveCoreStyle m_requested_save_core_style;
+ };
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
if (process_sp) {
if (command.GetArgumentCount() == 1) {
FileSpec output_file(command.GetArgumentAtIndex(0));
- Status error = PluginManager::SaveCore(process_sp, output_file);
+ SaveCoreStyle corefile_style = m_options.m_requested_save_core_style;
+ Status error =
+ PluginManager::SaveCore(process_sp, output_file, corefile_style);
if (error.Success()) {
+ if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly) {
+ result.AppendMessageWithFormat(
+ "\nModified-memory only corefile "
+ "created. This corefile may not show \n"
+ "library/framework/app binaries "
+ "on a different system, or when \n"
+ "those binaries have "
+ "been updated/modified. Copies are not included\n"
+ "in this corefile. Use --style full to include all "
+ "process memory.\n");
+ }
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
result.AppendErrorWithFormat(
@@ -1197,6 +1262,8 @@ protected:
return result.Succeeded();
}
+
+ CommandOptions m_options;
};
// CommandObjectProcessStatus