aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectTrace.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Commands/CommandObjectTrace.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectTrace.cpp116
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)));
}