174c93956SWalter Erquinigo //===-- CommandObjectTrace.cpp --------------------------------------------===// 274c93956SWalter Erquinigo // 374c93956SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 474c93956SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information. 574c93956SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 674c93956SWalter Erquinigo // 774c93956SWalter Erquinigo //===----------------------------------------------------------------------===// 874c93956SWalter Erquinigo 974c93956SWalter Erquinigo #include "CommandObjectTrace.h" 1074c93956SWalter Erquinigo 1174c93956SWalter Erquinigo #include "llvm/Support/JSON.h" 1274c93956SWalter Erquinigo #include "llvm/Support/MemoryBuffer.h" 1374c93956SWalter Erquinigo 1474c93956SWalter Erquinigo #include "lldb/Core/Debugger.h" 15ea1f4974SWalter Erquinigo #include "lldb/Core/PluginManager.h" 1674c93956SWalter Erquinigo #include "lldb/Host/OptionParser.h" 1774c93956SWalter Erquinigo #include "lldb/Interpreter/CommandInterpreter.h" 1874c93956SWalter Erquinigo #include "lldb/Interpreter/CommandObject.h" 1974c93956SWalter Erquinigo #include "lldb/Interpreter/CommandReturnObject.h" 2074c93956SWalter Erquinigo #include "lldb/Interpreter/OptionArgParser.h" 2174c93956SWalter Erquinigo #include "lldb/Interpreter/OptionGroupFormat.h" 2274c93956SWalter Erquinigo #include "lldb/Interpreter/OptionValueBoolean.h" 2374c93956SWalter Erquinigo #include "lldb/Interpreter/OptionValueLanguage.h" 2474c93956SWalter Erquinigo #include "lldb/Interpreter/OptionValueString.h" 2574c93956SWalter Erquinigo #include "lldb/Interpreter/Options.h" 260b697561SWalter Erquinigo #include "lldb/Target/Process.h" 2774c93956SWalter Erquinigo #include "lldb/Target/Trace.h" 2874c93956SWalter Erquinigo 2974c93956SWalter Erquinigo using namespace lldb; 3074c93956SWalter Erquinigo using namespace lldb_private; 3174c93956SWalter Erquinigo using namespace llvm; 3274c93956SWalter Erquinigo 33*b532dd54SWalter Erquinigo // CommandObjectTraceSave 34*b532dd54SWalter Erquinigo #define LLDB_OPTIONS_trace_save 35*b532dd54SWalter Erquinigo #include "CommandOptions.inc" 36*b532dd54SWalter Erquinigo 37*b532dd54SWalter Erquinigo #pragma mark CommandObjectTraceSave 38*b532dd54SWalter Erquinigo 39*b532dd54SWalter Erquinigo class CommandObjectTraceSave : public CommandObjectParsed { 40*b532dd54SWalter Erquinigo public: 41*b532dd54SWalter Erquinigo class CommandOptions : public Options { 42*b532dd54SWalter Erquinigo public: 43*b532dd54SWalter Erquinigo CommandOptions() { OptionParsingStarting(nullptr); } 44*b532dd54SWalter Erquinigo 45*b532dd54SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 46*b532dd54SWalter Erquinigo ExecutionContext *execution_context) override { 47*b532dd54SWalter Erquinigo Status error; 48*b532dd54SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 49*b532dd54SWalter Erquinigo 50*b532dd54SWalter Erquinigo switch (short_option) { 51*b532dd54SWalter Erquinigo case 'c': { 52*b532dd54SWalter Erquinigo m_compact = true; 53*b532dd54SWalter Erquinigo break; 54*b532dd54SWalter Erquinigo } 55*b532dd54SWalter Erquinigo default: 56*b532dd54SWalter Erquinigo llvm_unreachable("Unimplemented option"); 57*b532dd54SWalter Erquinigo } 58*b532dd54SWalter Erquinigo return error; 59*b532dd54SWalter Erquinigo } 60*b532dd54SWalter Erquinigo 61*b532dd54SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 62*b532dd54SWalter Erquinigo m_compact = false; 63*b532dd54SWalter Erquinigo }; 64*b532dd54SWalter Erquinigo 65*b532dd54SWalter Erquinigo llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 66*b532dd54SWalter Erquinigo return llvm::makeArrayRef(g_trace_save_options); 67*b532dd54SWalter Erquinigo }; 68*b532dd54SWalter Erquinigo 69*b532dd54SWalter Erquinigo bool m_compact; 70*b532dd54SWalter Erquinigo }; 71*b532dd54SWalter Erquinigo 72*b532dd54SWalter Erquinigo Options *GetOptions() override { return &m_options; } 73*b532dd54SWalter Erquinigo 74*b532dd54SWalter Erquinigo CommandObjectTraceSave(CommandInterpreter &interpreter) 75*b532dd54SWalter Erquinigo : CommandObjectParsed( 76*b532dd54SWalter Erquinigo interpreter, "trace save", 77*b532dd54SWalter Erquinigo "Save the trace of the current target in the specified directory, " 78*b532dd54SWalter Erquinigo "which will be created if needed. " 79*b532dd54SWalter Erquinigo "This directory will contain a trace bundle, with all the " 80*b532dd54SWalter Erquinigo "necessary files the reconstruct the trace session even on a " 81*b532dd54SWalter Erquinigo "different computer. " 82*b532dd54SWalter Erquinigo "Part of this bundle is the bundle description file with the name " 83*b532dd54SWalter Erquinigo "trace.json. This file can be used by the \"trace load\" command " 84*b532dd54SWalter Erquinigo "to load this trace in LLDB." 85*b532dd54SWalter Erquinigo "Note: if the current target contains information of multiple " 86*b532dd54SWalter Erquinigo "processes or targets, they all will be included in the bundle.", 87*b532dd54SWalter Erquinigo "trace save [<cmd-options>] <bundle_directory>", 88*b532dd54SWalter Erquinigo eCommandRequiresProcess | eCommandTryTargetAPILock | 89*b532dd54SWalter Erquinigo eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | 90*b532dd54SWalter Erquinigo eCommandProcessMustBeTraced) { 91*b532dd54SWalter Erquinigo CommandArgumentData bundle_dir{eArgTypeDirectoryName, eArgRepeatPlain}; 92*b532dd54SWalter Erquinigo m_arguments.push_back({bundle_dir}); 93*b532dd54SWalter Erquinigo } 94*b532dd54SWalter Erquinigo 95*b532dd54SWalter Erquinigo void 96*b532dd54SWalter Erquinigo HandleArgumentCompletion(CompletionRequest &request, 97*b532dd54SWalter Erquinigo OptionElementVector &opt_element_vector) override { 98*b532dd54SWalter Erquinigo CommandCompletions::InvokeCommonCompletionCallbacks( 99*b532dd54SWalter Erquinigo GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, 100*b532dd54SWalter Erquinigo request, nullptr); 101*b532dd54SWalter Erquinigo } 102*b532dd54SWalter Erquinigo 103*b532dd54SWalter Erquinigo ~CommandObjectTraceSave() override = default; 104*b532dd54SWalter Erquinigo 105*b532dd54SWalter Erquinigo protected: 106*b532dd54SWalter Erquinigo bool DoExecute(Args &command, CommandReturnObject &result) override { 107*b532dd54SWalter Erquinigo if (command.size() != 1) { 108*b532dd54SWalter Erquinigo result.AppendError("a single path to a directory where the trace bundle " 109*b532dd54SWalter Erquinigo "will be created is required"); 110*b532dd54SWalter Erquinigo return false; 111*b532dd54SWalter Erquinigo } 112*b532dd54SWalter Erquinigo 113*b532dd54SWalter Erquinigo FileSpec bundle_dir(command[0].ref()); 114*b532dd54SWalter Erquinigo FileSystem::Instance().Resolve(bundle_dir); 115*b532dd54SWalter Erquinigo 116*b532dd54SWalter Erquinigo ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 117*b532dd54SWalter Erquinigo 118*b532dd54SWalter Erquinigo TraceSP trace_sp = process_sp->GetTarget().GetTrace(); 119*b532dd54SWalter Erquinigo 120*b532dd54SWalter Erquinigo if (llvm::Expected<FileSpec> desc_file = 121*b532dd54SWalter Erquinigo trace_sp->SaveToDisk(bundle_dir, m_options.m_compact)) { 122*b532dd54SWalter Erquinigo result.AppendMessageWithFormatv( 123*b532dd54SWalter Erquinigo "Trace bundle description file written to: {0}", *desc_file); 124*b532dd54SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 125*b532dd54SWalter Erquinigo } else { 126*b532dd54SWalter Erquinigo result.AppendError(toString(desc_file.takeError())); 127*b532dd54SWalter Erquinigo } 128*b532dd54SWalter Erquinigo 129*b532dd54SWalter Erquinigo return result.Succeeded(); 130*b532dd54SWalter Erquinigo } 131*b532dd54SWalter Erquinigo 132*b532dd54SWalter Erquinigo CommandOptions m_options; 133*b532dd54SWalter Erquinigo }; 134*b532dd54SWalter Erquinigo 13574c93956SWalter Erquinigo // CommandObjectTraceLoad 13674c93956SWalter Erquinigo #define LLDB_OPTIONS_trace_load 13774c93956SWalter Erquinigo #include "CommandOptions.inc" 13874c93956SWalter Erquinigo 13974c93956SWalter Erquinigo #pragma mark CommandObjectTraceLoad 14074c93956SWalter Erquinigo 14174c93956SWalter Erquinigo class CommandObjectTraceLoad : public CommandObjectParsed { 14274c93956SWalter Erquinigo public: 14374c93956SWalter Erquinigo class CommandOptions : public Options { 14474c93956SWalter Erquinigo public: 145abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); } 14674c93956SWalter Erquinigo 14774c93956SWalter Erquinigo ~CommandOptions() override = default; 14874c93956SWalter Erquinigo 14974c93956SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, StringRef option_arg, 15074c93956SWalter Erquinigo ExecutionContext *execution_context) override { 15174c93956SWalter Erquinigo Status error; 15274c93956SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 15374c93956SWalter Erquinigo 15474c93956SWalter Erquinigo switch (short_option) { 15574c93956SWalter Erquinigo case 'v': { 15674c93956SWalter Erquinigo m_verbose = true; 15774c93956SWalter Erquinigo break; 15874c93956SWalter Erquinigo } 15974c93956SWalter Erquinigo default: 16074c93956SWalter Erquinigo llvm_unreachable("Unimplemented option"); 16174c93956SWalter Erquinigo } 16274c93956SWalter Erquinigo return error; 16374c93956SWalter Erquinigo } 16474c93956SWalter Erquinigo 16574c93956SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 16674c93956SWalter Erquinigo m_verbose = false; 16774c93956SWalter Erquinigo } 16874c93956SWalter Erquinigo 16974c93956SWalter Erquinigo ArrayRef<OptionDefinition> GetDefinitions() override { 17074c93956SWalter Erquinigo return makeArrayRef(g_trace_load_options); 17174c93956SWalter Erquinigo } 17274c93956SWalter Erquinigo 17374c93956SWalter Erquinigo bool m_verbose; // Enable verbose logging for debugging purposes. 17474c93956SWalter Erquinigo }; 17574c93956SWalter Erquinigo 17674c93956SWalter Erquinigo CommandObjectTraceLoad(CommandInterpreter &interpreter) 177b8dcd0baSWalter Erquinigo : CommandObjectParsed( 178b8dcd0baSWalter Erquinigo interpreter, "trace load", 179b8dcd0baSWalter Erquinigo "Load a post-mortem processor trace session from a trace bundle.", 180*b532dd54SWalter Erquinigo "trace load <trace_description_file>") { 181*b532dd54SWalter Erquinigo CommandArgumentData session_file_arg{eArgTypeFilename, eArgRepeatPlain}; 182c1b07d61SJim Ingham m_arguments.push_back({session_file_arg}); 183c1b07d61SJim Ingham } 18474c93956SWalter Erquinigo 185*b532dd54SWalter Erquinigo void 186*b532dd54SWalter Erquinigo HandleArgumentCompletion(CompletionRequest &request, 187*b532dd54SWalter Erquinigo OptionElementVector &opt_element_vector) override { 188*b532dd54SWalter Erquinigo CommandCompletions::InvokeCommonCompletionCallbacks( 189*b532dd54SWalter Erquinigo GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, 190*b532dd54SWalter Erquinigo request, nullptr); 191*b532dd54SWalter Erquinigo } 192*b532dd54SWalter Erquinigo 19374c93956SWalter Erquinigo ~CommandObjectTraceLoad() override = default; 19474c93956SWalter Erquinigo 19574c93956SWalter Erquinigo Options *GetOptions() override { return &m_options; } 19674c93956SWalter Erquinigo 19774c93956SWalter Erquinigo protected: 19874c93956SWalter Erquinigo bool DoExecute(Args &command, CommandReturnObject &result) override { 19974c93956SWalter Erquinigo if (command.size() != 1) { 200b8dcd0baSWalter Erquinigo result.AppendError("a single path to a JSON file containing a the " 201b8dcd0baSWalter Erquinigo "description of the trace bundle is required"); 20274c93956SWalter Erquinigo return false; 20374c93956SWalter Erquinigo } 20474c93956SWalter Erquinigo 20550f93679SJakob Johnson const FileSpec trace_description_file(command[0].ref()); 20650f93679SJakob Johnson 20750f93679SJakob Johnson llvm::Expected<lldb::TraceSP> trace_or_err = 20850f93679SJakob Johnson Trace::LoadPostMortemTraceFromFile(GetDebugger(), 20950f93679SJakob Johnson trace_description_file); 21050f93679SJakob Johnson 21150f93679SJakob Johnson if (!trace_or_err) { 21250f93679SJakob Johnson result.AppendErrorWithFormat( 21350f93679SJakob Johnson "%s\n", llvm::toString(trace_or_err.takeError()).c_str()); 21474c93956SWalter Erquinigo return false; 21574c93956SWalter Erquinigo } 21674c93956SWalter Erquinigo 21750f93679SJakob Johnson if (m_options.m_verbose) { 218a3939e15SPavel Labath result.AppendMessageWithFormatv("loading trace with plugin {0}\n", 21950f93679SJakob Johnson trace_or_err.get()->GetPluginName()); 22050f93679SJakob Johnson } 22174c93956SWalter Erquinigo 22274c93956SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 22374c93956SWalter Erquinigo return true; 22474c93956SWalter Erquinigo } 22574c93956SWalter Erquinigo 22674c93956SWalter Erquinigo CommandOptions m_options; 22774c93956SWalter Erquinigo }; 22874c93956SWalter Erquinigo 22974c93956SWalter Erquinigo // CommandObjectTraceDump 23074c93956SWalter Erquinigo #define LLDB_OPTIONS_trace_dump 23174c93956SWalter Erquinigo #include "CommandOptions.inc" 23274c93956SWalter Erquinigo 23374c93956SWalter Erquinigo #pragma mark CommandObjectTraceDump 23474c93956SWalter Erquinigo 23574c93956SWalter Erquinigo class CommandObjectTraceDump : public CommandObjectParsed { 23674c93956SWalter Erquinigo public: 23774c93956SWalter Erquinigo class CommandOptions : public Options { 23874c93956SWalter Erquinigo public: 239abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); } 24074c93956SWalter Erquinigo 24174c93956SWalter Erquinigo ~CommandOptions() override = default; 24274c93956SWalter Erquinigo 24374c93956SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 24474c93956SWalter Erquinigo ExecutionContext *execution_context) override { 24574c93956SWalter Erquinigo Status error; 24674c93956SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 24774c93956SWalter Erquinigo 24874c93956SWalter Erquinigo switch (short_option) { 24974c93956SWalter Erquinigo case 'v': { 25074c93956SWalter Erquinigo m_verbose = true; 25174c93956SWalter Erquinigo break; 25274c93956SWalter Erquinigo } 25374c93956SWalter Erquinigo default: 25474c93956SWalter Erquinigo llvm_unreachable("Unimplemented option"); 25574c93956SWalter Erquinigo } 25674c93956SWalter Erquinigo return error; 25774c93956SWalter Erquinigo } 25874c93956SWalter Erquinigo 25974c93956SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 26074c93956SWalter Erquinigo m_verbose = false; 26174c93956SWalter Erquinigo } 26274c93956SWalter Erquinigo 26374c93956SWalter Erquinigo llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 26474c93956SWalter Erquinigo return llvm::makeArrayRef(g_trace_dump_options); 26574c93956SWalter Erquinigo } 26674c93956SWalter Erquinigo 26774c93956SWalter Erquinigo bool m_verbose; // Enable verbose logging for debugging purposes. 26874c93956SWalter Erquinigo }; 26974c93956SWalter Erquinigo 27074c93956SWalter Erquinigo CommandObjectTraceDump(CommandInterpreter &interpreter) 27174c93956SWalter Erquinigo : CommandObjectParsed(interpreter, "trace dump", 27274c93956SWalter Erquinigo "Dump the loaded processor trace data.", 273abb0ed44SKazu Hirata "trace dump") {} 27474c93956SWalter Erquinigo 27574c93956SWalter Erquinigo ~CommandObjectTraceDump() override = default; 27674c93956SWalter Erquinigo 27774c93956SWalter Erquinigo Options *GetOptions() override { return &m_options; } 27874c93956SWalter Erquinigo 27974c93956SWalter Erquinigo protected: 28074c93956SWalter Erquinigo bool DoExecute(Args &command, CommandReturnObject &result) override { 28174c93956SWalter Erquinigo Status error; 28274c93956SWalter Erquinigo // TODO: fill in the dumping code here! 28374c93956SWalter Erquinigo if (error.Success()) { 28474c93956SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 28574c93956SWalter Erquinigo } else { 28674c93956SWalter Erquinigo result.AppendErrorWithFormat("%s\n", error.AsCString()); 28774c93956SWalter Erquinigo } 28874c93956SWalter Erquinigo return result.Succeeded(); 28974c93956SWalter Erquinigo } 29074c93956SWalter Erquinigo 29174c93956SWalter Erquinigo CommandOptions m_options; 29274c93956SWalter Erquinigo }; 29374c93956SWalter Erquinigo 29474c93956SWalter Erquinigo // CommandObjectTraceSchema 29574c93956SWalter Erquinigo #define LLDB_OPTIONS_trace_schema 29674c93956SWalter Erquinigo #include "CommandOptions.inc" 29774c93956SWalter Erquinigo 29874c93956SWalter Erquinigo #pragma mark CommandObjectTraceSchema 29974c93956SWalter Erquinigo 30074c93956SWalter Erquinigo class CommandObjectTraceSchema : public CommandObjectParsed { 30174c93956SWalter Erquinigo public: 30274c93956SWalter Erquinigo class CommandOptions : public Options { 30374c93956SWalter Erquinigo public: 304abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); } 30574c93956SWalter Erquinigo 30674c93956SWalter Erquinigo ~CommandOptions() override = default; 30774c93956SWalter Erquinigo 30874c93956SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 30974c93956SWalter Erquinigo ExecutionContext *execution_context) override { 31074c93956SWalter Erquinigo Status error; 31174c93956SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 31274c93956SWalter Erquinigo 31374c93956SWalter Erquinigo switch (short_option) { 31474c93956SWalter Erquinigo case 'v': { 31574c93956SWalter Erquinigo m_verbose = true; 31674c93956SWalter Erquinigo break; 31774c93956SWalter Erquinigo } 31874c93956SWalter Erquinigo default: 31974c93956SWalter Erquinigo llvm_unreachable("Unimplemented option"); 32074c93956SWalter Erquinigo } 32174c93956SWalter Erquinigo return error; 32274c93956SWalter Erquinigo } 32374c93956SWalter Erquinigo 32474c93956SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 32574c93956SWalter Erquinigo m_verbose = false; 32674c93956SWalter Erquinigo } 32774c93956SWalter Erquinigo 32874c93956SWalter Erquinigo llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 32974c93956SWalter Erquinigo return llvm::makeArrayRef(g_trace_schema_options); 33074c93956SWalter Erquinigo } 33174c93956SWalter Erquinigo 33274c93956SWalter Erquinigo bool m_verbose; // Enable verbose logging for debugging purposes. 33374c93956SWalter Erquinigo }; 33474c93956SWalter Erquinigo 33574c93956SWalter Erquinigo CommandObjectTraceSchema(CommandInterpreter &interpreter) 33674c93956SWalter Erquinigo : CommandObjectParsed(interpreter, "trace schema", 33774c93956SWalter Erquinigo "Show the schema of the given trace plugin.", 338ea1f4974SWalter Erquinigo "trace schema <plug-in>. Use the plug-in name " 339c1b07d61SJim Ingham "\"all\" to see all schemas.\n") { 340c1b07d61SJim Ingham CommandArgumentData plugin_arg{eArgTypeNone, eArgRepeatPlain}; 341c1b07d61SJim Ingham m_arguments.push_back({plugin_arg}); 342c1b07d61SJim Ingham } 34374c93956SWalter Erquinigo 34474c93956SWalter Erquinigo ~CommandObjectTraceSchema() override = default; 34574c93956SWalter Erquinigo 34674c93956SWalter Erquinigo Options *GetOptions() override { return &m_options; } 34774c93956SWalter Erquinigo 34874c93956SWalter Erquinigo protected: 34974c93956SWalter Erquinigo bool DoExecute(Args &command, CommandReturnObject &result) override { 35074c93956SWalter Erquinigo Status error; 35174c93956SWalter Erquinigo if (command.empty()) { 3521b1c8e4aSDavid Spickett result.AppendError( 35374c93956SWalter Erquinigo "trace schema cannot be invoked without a plug-in as argument"); 35474c93956SWalter Erquinigo return false; 35574c93956SWalter Erquinigo } 35674c93956SWalter Erquinigo 35774c93956SWalter Erquinigo StringRef plugin_name(command[0].c_str()); 358ea1f4974SWalter Erquinigo if (plugin_name == "all") { 359ea1f4974SWalter Erquinigo size_t index = 0; 360ea1f4974SWalter Erquinigo while (true) { 361ea1f4974SWalter Erquinigo StringRef schema = PluginManager::GetTraceSchema(index++); 362ea1f4974SWalter Erquinigo if (schema.empty()) 363ea1f4974SWalter Erquinigo break; 36474c93956SWalter Erquinigo 365ea1f4974SWalter Erquinigo result.AppendMessage(schema); 366ea1f4974SWalter Erquinigo } 36774c93956SWalter Erquinigo } else { 368ea1f4974SWalter Erquinigo if (Expected<StringRef> schemaOrErr = 369ea1f4974SWalter Erquinigo Trace::FindPluginSchema(plugin_name)) 370ea1f4974SWalter Erquinigo result.AppendMessage(*schemaOrErr); 371ea1f4974SWalter Erquinigo else 372ea1f4974SWalter Erquinigo error = schemaOrErr.takeError(); 37374c93956SWalter Erquinigo } 37474c93956SWalter Erquinigo 37574c93956SWalter Erquinigo if (error.Success()) { 37674c93956SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 37774c93956SWalter Erquinigo } else { 37874c93956SWalter Erquinigo result.AppendErrorWithFormat("%s\n", error.AsCString()); 37974c93956SWalter Erquinigo } 38074c93956SWalter Erquinigo return result.Succeeded(); 38174c93956SWalter Erquinigo } 38274c93956SWalter Erquinigo 38374c93956SWalter Erquinigo CommandOptions m_options; 38474c93956SWalter Erquinigo }; 38574c93956SWalter Erquinigo 38674c93956SWalter Erquinigo // CommandObjectTrace 38774c93956SWalter Erquinigo 38874c93956SWalter Erquinigo CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter) 38974c93956SWalter Erquinigo : CommandObjectMultiword(interpreter, "trace", 39074c93956SWalter Erquinigo "Commands for loading and using processor " 39174c93956SWalter Erquinigo "trace information.", 39274c93956SWalter Erquinigo "trace [<sub-command-options>]") { 39374c93956SWalter Erquinigo LoadSubCommand("load", 39474c93956SWalter Erquinigo CommandObjectSP(new CommandObjectTraceLoad(interpreter))); 39574c93956SWalter Erquinigo LoadSubCommand("dump", 39674c93956SWalter Erquinigo CommandObjectSP(new CommandObjectTraceDump(interpreter))); 397*b532dd54SWalter Erquinigo LoadSubCommand("save", 398*b532dd54SWalter Erquinigo CommandObjectSP(new CommandObjectTraceSave(interpreter))); 39974c93956SWalter Erquinigo LoadSubCommand("schema", 40074c93956SWalter Erquinigo CommandObjectSP(new CommandObjectTraceSchema(interpreter))); 40174c93956SWalter Erquinigo } 40274c93956SWalter Erquinigo 40374c93956SWalter Erquinigo CommandObjectTrace::~CommandObjectTrace() = default; 4040b697561SWalter Erquinigo 4050b697561SWalter Erquinigo Expected<CommandObjectSP> CommandObjectTraceProxy::DoGetProxyCommandObject() { 4060b697561SWalter Erquinigo ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP(); 4070b697561SWalter Erquinigo 4080b697561SWalter Erquinigo if (!process_sp) 4090b697561SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 4100b697561SWalter Erquinigo "Process not available."); 4110b697561SWalter Erquinigo if (m_live_debug_session_only && !process_sp->IsLiveDebugSession()) 4120b697561SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 4130b697561SWalter Erquinigo "Process must be alive."); 4140b697561SWalter Erquinigo 415bf9f21a2SWalter Erquinigo if (Expected<TraceSP> trace_sp = process_sp->GetTarget().GetTraceOrCreate()) 4160b697561SWalter Erquinigo return GetDelegateCommand(**trace_sp); 4170b697561SWalter Erquinigo else 4180b697561SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 4190b697561SWalter Erquinigo "Tracing is not supported. %s", 4200b697561SWalter Erquinigo toString(trace_sp.takeError()).c_str()); 4210b697561SWalter Erquinigo } 4220b697561SWalter Erquinigo 4230b697561SWalter Erquinigo CommandObject *CommandObjectTraceProxy::GetProxyCommandObject() { 4240b697561SWalter Erquinigo if (Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) { 4250b697561SWalter Erquinigo m_delegate_sp = *delegate; 4260b697561SWalter Erquinigo m_delegate_error.clear(); 4270b697561SWalter Erquinigo return m_delegate_sp.get(); 4280b697561SWalter Erquinigo } else { 4290b697561SWalter Erquinigo m_delegate_sp.reset(); 4300b697561SWalter Erquinigo m_delegate_error = toString(delegate.takeError()); 4310b697561SWalter Erquinigo return nullptr; 4320b697561SWalter Erquinigo } 4330b697561SWalter Erquinigo } 434