diff options
Diffstat (limited to 'lldb/source/Commands/CommandObjectTrace.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectTrace.cpp | 116 |
1 files changed, 114 insertions, 2 deletions
diff --git a/lldb/source/Commands/CommandObjectTrace.cpp b/lldb/source/Commands/CommandObjectTrace.cpp index 17aded9ed2a0..227de2de7065 100644 --- a/lldb/source/Commands/CommandObjectTrace.cpp +++ b/lldb/source/Commands/CommandObjectTrace.cpp @@ -30,6 +30,108 @@ using namespace lldb; using namespace lldb_private; using namespace llvm; +// CommandObjectTraceSave +#define LLDB_OPTIONS_trace_save +#include "CommandOptions.inc" + +#pragma mark CommandObjectTraceSave + +class CommandObjectTraceSave : public CommandObjectParsed { +public: + class CommandOptions : public Options { + public: + CommandOptions() { OptionParsingStarting(nullptr); } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'c': { + m_compact = true; + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_compact = false; + }; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_trace_save_options); + }; + + bool m_compact; + }; + + Options *GetOptions() override { return &m_options; } + + CommandObjectTraceSave(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "trace save", + "Save the trace of the current target in the specified directory, " + "which will be created if needed. " + "This directory will contain a trace bundle, with all the " + "necessary files the reconstruct the trace session even on a " + "different computer. " + "Part of this bundle is the bundle description file with the name " + "trace.json. This file can be used by the \"trace load\" command " + "to load this trace in LLDB." + "Note: if the current target contains information of multiple " + "processes or targets, they all will be included in the bundle.", + "trace save [<cmd-options>] <bundle_directory>", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | + eCommandProcessMustBeTraced) { + CommandArgumentData bundle_dir{eArgTypeDirectoryName, eArgRepeatPlain}; + m_arguments.push_back({bundle_dir}); + } + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, + request, nullptr); + } + + ~CommandObjectTraceSave() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.size() != 1) { + result.AppendError("a single path to a directory where the trace bundle " + "will be created is required"); + return false; + } + + FileSpec bundle_dir(command[0].ref()); + FileSystem::Instance().Resolve(bundle_dir); + + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); + + TraceSP trace_sp = process_sp->GetTarget().GetTrace(); + + if (llvm::Expected<FileSpec> desc_file = + trace_sp->SaveToDisk(bundle_dir, m_options.m_compact)) { + result.AppendMessageWithFormatv( + "Trace bundle description file written to: {0}", *desc_file); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError(toString(desc_file.takeError())); + } + + return result.Succeeded(); + } + + CommandOptions m_options; +}; + // CommandObjectTraceLoad #define LLDB_OPTIONS_trace_load #include "CommandOptions.inc" @@ -75,11 +177,19 @@ public: : CommandObjectParsed( interpreter, "trace load", "Load a post-mortem processor trace session from a trace bundle.", - "trace load") { - CommandArgumentData session_file_arg{eArgTypePath, eArgRepeatPlain}; + "trace load <trace_description_file>") { + CommandArgumentData session_file_arg{eArgTypeFilename, eArgRepeatPlain}; m_arguments.push_back({session_file_arg}); } + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, + request, nullptr); + } + ~CommandObjectTraceLoad() override = default; Options *GetOptions() override { return &m_options; } @@ -284,6 +394,8 @@ CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter) CommandObjectSP(new CommandObjectTraceLoad(interpreter))); LoadSubCommand("dump", CommandObjectSP(new CommandObjectTraceDump(interpreter))); + LoadSubCommand("save", + CommandObjectSP(new CommandObjectTraceSave(interpreter))); LoadSubCommand("schema", CommandObjectSP(new CommandObjectTraceSchema(interpreter))); } |