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" 197ced9fffSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h" 2074c93956SWalter Erquinigo #include "lldb/Interpreter/CommandReturnObject.h" 2174c93956SWalter Erquinigo #include "lldb/Interpreter/OptionArgParser.h" 2274c93956SWalter Erquinigo #include "lldb/Interpreter/OptionGroupFormat.h" 2374c93956SWalter Erquinigo #include "lldb/Interpreter/OptionValueBoolean.h" 2474c93956SWalter Erquinigo #include "lldb/Interpreter/OptionValueLanguage.h" 2574c93956SWalter Erquinigo #include "lldb/Interpreter/OptionValueString.h" 2674c93956SWalter Erquinigo #include "lldb/Interpreter/Options.h" 270b697561SWalter Erquinigo #include "lldb/Target/Process.h" 2874c93956SWalter Erquinigo #include "lldb/Target/Trace.h" 2974c93956SWalter Erquinigo 3074c93956SWalter Erquinigo using namespace lldb; 3174c93956SWalter Erquinigo using namespace lldb_private; 3274c93956SWalter Erquinigo using namespace llvm; 3374c93956SWalter Erquinigo 34b532dd54SWalter Erquinigo // CommandObjectTraceSave 35b532dd54SWalter Erquinigo #define LLDB_OPTIONS_trace_save 36b532dd54SWalter Erquinigo #include "CommandOptions.inc" 37b532dd54SWalter Erquinigo 38b532dd54SWalter Erquinigo #pragma mark CommandObjectTraceSave 39b532dd54SWalter Erquinigo 40b532dd54SWalter Erquinigo class CommandObjectTraceSave : public CommandObjectParsed { 41b532dd54SWalter Erquinigo public: 42b532dd54SWalter Erquinigo class CommandOptions : public Options { 43b532dd54SWalter Erquinigo public: 44b532dd54SWalter Erquinigo CommandOptions() { OptionParsingStarting(nullptr); } 45b532dd54SWalter Erquinigo 46b532dd54SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 47b532dd54SWalter Erquinigo ExecutionContext *execution_context) override { 48b532dd54SWalter Erquinigo Status error; 49b532dd54SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 50b532dd54SWalter Erquinigo 51b532dd54SWalter Erquinigo switch (short_option) { 52b532dd54SWalter Erquinigo case 'c': { 53b532dd54SWalter Erquinigo m_compact = true; 54b532dd54SWalter Erquinigo break; 55b532dd54SWalter Erquinigo } 56b532dd54SWalter Erquinigo default: 57b532dd54SWalter Erquinigo llvm_unreachable("Unimplemented option"); 58b532dd54SWalter Erquinigo } 59b532dd54SWalter Erquinigo return error; 60b532dd54SWalter Erquinigo } 61b532dd54SWalter Erquinigo 62b532dd54SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 63b532dd54SWalter Erquinigo m_compact = false; 64b532dd54SWalter Erquinigo }; 65b532dd54SWalter Erquinigo 66b532dd54SWalter Erquinigo llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 67984b800aSserge-sans-paille return llvm::ArrayRef(g_trace_save_options); 68b532dd54SWalter Erquinigo }; 69b532dd54SWalter Erquinigo 70b532dd54SWalter Erquinigo bool m_compact; 71b532dd54SWalter Erquinigo }; 72b532dd54SWalter Erquinigo 73b532dd54SWalter Erquinigo Options *GetOptions() override { return &m_options; } 74b532dd54SWalter Erquinigo 75b532dd54SWalter Erquinigo CommandObjectTraceSave(CommandInterpreter &interpreter) 76b532dd54SWalter Erquinigo : CommandObjectParsed( 77b532dd54SWalter Erquinigo interpreter, "trace save", 78b532dd54SWalter Erquinigo "Save the trace of the current target in the specified directory, " 79b532dd54SWalter Erquinigo "which will be created if needed. " 80b532dd54SWalter Erquinigo "This directory will contain a trace bundle, with all the " 81b532dd54SWalter Erquinigo "necessary files the reconstruct the trace session even on a " 82b532dd54SWalter Erquinigo "different computer. " 83b532dd54SWalter Erquinigo "Part of this bundle is the bundle description file with the name " 84b532dd54SWalter Erquinigo "trace.json. This file can be used by the \"trace load\" command " 85b532dd54SWalter Erquinigo "to load this trace in LLDB." 86b532dd54SWalter Erquinigo "Note: if the current target contains information of multiple " 87b532dd54SWalter Erquinigo "processes or targets, they all will be included in the bundle.", 88b532dd54SWalter Erquinigo "trace save [<cmd-options>] <bundle_directory>", 89b532dd54SWalter Erquinigo eCommandRequiresProcess | eCommandTryTargetAPILock | 90b532dd54SWalter Erquinigo eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | 91b532dd54SWalter Erquinigo eCommandProcessMustBeTraced) { 922d704f4bSjimingham AddSimpleArgumentList(eArgTypeDirectoryName); 93b532dd54SWalter Erquinigo } 94b532dd54SWalter Erquinigo 95b532dd54SWalter Erquinigo void 96b532dd54SWalter Erquinigo HandleArgumentCompletion(CompletionRequest &request, 97b532dd54SWalter Erquinigo OptionElementVector &opt_element_vector) override { 986a9c3e61SMed Ismail Bennani lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 996a9c3e61SMed Ismail Bennani GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); 100b532dd54SWalter Erquinigo } 101b532dd54SWalter Erquinigo 102b532dd54SWalter Erquinigo ~CommandObjectTraceSave() override = default; 103b532dd54SWalter Erquinigo 104b532dd54SWalter Erquinigo protected: 10592d8a28cSPete Lawrence void DoExecute(Args &command, CommandReturnObject &result) override { 106b532dd54SWalter Erquinigo if (command.size() != 1) { 107b532dd54SWalter Erquinigo result.AppendError("a single path to a directory where the trace bundle " 108b532dd54SWalter Erquinigo "will be created is required"); 10992d8a28cSPete Lawrence return; 110b532dd54SWalter Erquinigo } 111b532dd54SWalter Erquinigo 112b532dd54SWalter Erquinigo FileSpec bundle_dir(command[0].ref()); 113b532dd54SWalter Erquinigo FileSystem::Instance().Resolve(bundle_dir); 114b532dd54SWalter Erquinigo 115b532dd54SWalter Erquinigo ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 116b532dd54SWalter Erquinigo 117b532dd54SWalter Erquinigo TraceSP trace_sp = process_sp->GetTarget().GetTrace(); 118b532dd54SWalter Erquinigo 119b532dd54SWalter Erquinigo if (llvm::Expected<FileSpec> desc_file = 120b532dd54SWalter Erquinigo trace_sp->SaveToDisk(bundle_dir, m_options.m_compact)) { 121b532dd54SWalter Erquinigo result.AppendMessageWithFormatv( 122b532dd54SWalter Erquinigo "Trace bundle description file written to: {0}", *desc_file); 123b532dd54SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 124b532dd54SWalter Erquinigo } else { 125b532dd54SWalter Erquinigo result.AppendError(toString(desc_file.takeError())); 126b532dd54SWalter Erquinigo } 127b532dd54SWalter Erquinigo } 128b532dd54SWalter Erquinigo 129b532dd54SWalter Erquinigo CommandOptions m_options; 130b532dd54SWalter Erquinigo }; 131b532dd54SWalter Erquinigo 13274c93956SWalter Erquinigo // CommandObjectTraceLoad 13374c93956SWalter Erquinigo #define LLDB_OPTIONS_trace_load 13474c93956SWalter Erquinigo #include "CommandOptions.inc" 13574c93956SWalter Erquinigo 13674c93956SWalter Erquinigo #pragma mark CommandObjectTraceLoad 13774c93956SWalter Erquinigo 13874c93956SWalter Erquinigo class CommandObjectTraceLoad : public CommandObjectParsed { 13974c93956SWalter Erquinigo public: 14074c93956SWalter Erquinigo class CommandOptions : public Options { 14174c93956SWalter Erquinigo public: 142abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); } 14374c93956SWalter Erquinigo 14474c93956SWalter Erquinigo ~CommandOptions() override = default; 14574c93956SWalter Erquinigo 14674c93956SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, StringRef option_arg, 14774c93956SWalter Erquinigo ExecutionContext *execution_context) override { 14874c93956SWalter Erquinigo Status error; 14974c93956SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 15074c93956SWalter Erquinigo 15174c93956SWalter Erquinigo switch (short_option) { 15274c93956SWalter Erquinigo case 'v': { 15374c93956SWalter Erquinigo m_verbose = true; 15474c93956SWalter Erquinigo break; 15574c93956SWalter Erquinigo } 15674c93956SWalter Erquinigo default: 15774c93956SWalter Erquinigo llvm_unreachable("Unimplemented option"); 15874c93956SWalter Erquinigo } 15974c93956SWalter Erquinigo return error; 16074c93956SWalter Erquinigo } 16174c93956SWalter Erquinigo 16274c93956SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 16374c93956SWalter Erquinigo m_verbose = false; 16474c93956SWalter Erquinigo } 16574c93956SWalter Erquinigo 16674c93956SWalter Erquinigo ArrayRef<OptionDefinition> GetDefinitions() override { 167984b800aSserge-sans-paille return ArrayRef(g_trace_load_options); 16874c93956SWalter Erquinigo } 16974c93956SWalter Erquinigo 17074c93956SWalter Erquinigo bool m_verbose; // Enable verbose logging for debugging purposes. 17174c93956SWalter Erquinigo }; 17274c93956SWalter Erquinigo 17374c93956SWalter Erquinigo CommandObjectTraceLoad(CommandInterpreter &interpreter) 174b8dcd0baSWalter Erquinigo : CommandObjectParsed( 175b8dcd0baSWalter Erquinigo interpreter, "trace load", 176b8dcd0baSWalter Erquinigo "Load a post-mortem processor trace session from a trace bundle.", 177b532dd54SWalter Erquinigo "trace load <trace_description_file>") { 1782d704f4bSjimingham AddSimpleArgumentList(eArgTypeFilename); 179c1b07d61SJim Ingham } 18074c93956SWalter Erquinigo 181b532dd54SWalter Erquinigo void 182b532dd54SWalter Erquinigo HandleArgumentCompletion(CompletionRequest &request, 183b532dd54SWalter Erquinigo OptionElementVector &opt_element_vector) override { 1846a9c3e61SMed Ismail Bennani lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 1856a9c3e61SMed Ismail Bennani GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); 186b532dd54SWalter Erquinigo } 187b532dd54SWalter Erquinigo 18874c93956SWalter Erquinigo ~CommandObjectTraceLoad() override = default; 18974c93956SWalter Erquinigo 19074c93956SWalter Erquinigo Options *GetOptions() override { return &m_options; } 19174c93956SWalter Erquinigo 19274c93956SWalter Erquinigo protected: 19392d8a28cSPete Lawrence void DoExecute(Args &command, CommandReturnObject &result) override { 19474c93956SWalter Erquinigo if (command.size() != 1) { 195b8dcd0baSWalter Erquinigo result.AppendError("a single path to a JSON file containing a the " 196b8dcd0baSWalter Erquinigo "description of the trace bundle is required"); 19792d8a28cSPete Lawrence return; 19874c93956SWalter Erquinigo } 19974c93956SWalter Erquinigo 20050f93679SJakob Johnson const FileSpec trace_description_file(command[0].ref()); 20150f93679SJakob Johnson 20250f93679SJakob Johnson llvm::Expected<lldb::TraceSP> trace_or_err = 20350f93679SJakob Johnson Trace::LoadPostMortemTraceFromFile(GetDebugger(), 20450f93679SJakob Johnson trace_description_file); 20550f93679SJakob Johnson 20650f93679SJakob Johnson if (!trace_or_err) { 20750f93679SJakob Johnson result.AppendErrorWithFormat( 20850f93679SJakob Johnson "%s\n", llvm::toString(trace_or_err.takeError()).c_str()); 20992d8a28cSPete Lawrence return; 21074c93956SWalter Erquinigo } 21174c93956SWalter Erquinigo 21250f93679SJakob Johnson if (m_options.m_verbose) { 213a3939e15SPavel Labath result.AppendMessageWithFormatv("loading trace with plugin {0}\n", 21450f93679SJakob Johnson trace_or_err.get()->GetPluginName()); 21550f93679SJakob Johnson } 21674c93956SWalter Erquinigo 21774c93956SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 21874c93956SWalter Erquinigo } 21974c93956SWalter Erquinigo 22074c93956SWalter Erquinigo CommandOptions m_options; 22174c93956SWalter Erquinigo }; 22274c93956SWalter Erquinigo 22374c93956SWalter Erquinigo // CommandObjectTraceDump 22474c93956SWalter Erquinigo #define LLDB_OPTIONS_trace_dump 22574c93956SWalter Erquinigo #include "CommandOptions.inc" 22674c93956SWalter Erquinigo 22774c93956SWalter Erquinigo #pragma mark CommandObjectTraceDump 22874c93956SWalter Erquinigo 22974c93956SWalter Erquinigo class CommandObjectTraceDump : public CommandObjectParsed { 23074c93956SWalter Erquinigo public: 23174c93956SWalter Erquinigo class CommandOptions : public Options { 23274c93956SWalter Erquinigo public: 233abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); } 23474c93956SWalter Erquinigo 23574c93956SWalter Erquinigo ~CommandOptions() override = default; 23674c93956SWalter Erquinigo 23774c93956SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 23874c93956SWalter Erquinigo ExecutionContext *execution_context) override { 23974c93956SWalter Erquinigo Status error; 24074c93956SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 24174c93956SWalter Erquinigo 24274c93956SWalter Erquinigo switch (short_option) { 24374c93956SWalter Erquinigo case 'v': { 24474c93956SWalter Erquinigo m_verbose = true; 24574c93956SWalter Erquinigo break; 24674c93956SWalter Erquinigo } 24774c93956SWalter Erquinigo default: 24874c93956SWalter Erquinigo llvm_unreachable("Unimplemented option"); 24974c93956SWalter Erquinigo } 25074c93956SWalter Erquinigo return error; 25174c93956SWalter Erquinigo } 25274c93956SWalter Erquinigo 25374c93956SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 25474c93956SWalter Erquinigo m_verbose = false; 25574c93956SWalter Erquinigo } 25674c93956SWalter Erquinigo 25774c93956SWalter Erquinigo llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 258984b800aSserge-sans-paille return llvm::ArrayRef(g_trace_dump_options); 25974c93956SWalter Erquinigo } 26074c93956SWalter Erquinigo 26174c93956SWalter Erquinigo bool m_verbose; // Enable verbose logging for debugging purposes. 26274c93956SWalter Erquinigo }; 26374c93956SWalter Erquinigo 26474c93956SWalter Erquinigo CommandObjectTraceDump(CommandInterpreter &interpreter) 26574c93956SWalter Erquinigo : CommandObjectParsed(interpreter, "trace dump", 26674c93956SWalter Erquinigo "Dump the loaded processor trace data.", 267abb0ed44SKazu Hirata "trace dump") {} 26874c93956SWalter Erquinigo 26974c93956SWalter Erquinigo ~CommandObjectTraceDump() override = default; 27074c93956SWalter Erquinigo 27174c93956SWalter Erquinigo Options *GetOptions() override { return &m_options; } 27274c93956SWalter Erquinigo 27374c93956SWalter Erquinigo protected: 27492d8a28cSPete Lawrence void DoExecute(Args &command, CommandReturnObject &result) override { 27574c93956SWalter Erquinigo Status error; 27674c93956SWalter Erquinigo // TODO: fill in the dumping code here! 27774c93956SWalter Erquinigo if (error.Success()) { 27874c93956SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 27974c93956SWalter Erquinigo } else { 28074c93956SWalter Erquinigo result.AppendErrorWithFormat("%s\n", error.AsCString()); 28174c93956SWalter Erquinigo } 28274c93956SWalter Erquinigo } 28374c93956SWalter Erquinigo 28474c93956SWalter Erquinigo CommandOptions m_options; 28574c93956SWalter Erquinigo }; 28674c93956SWalter Erquinigo 28774c93956SWalter Erquinigo // CommandObjectTraceSchema 28874c93956SWalter Erquinigo #define LLDB_OPTIONS_trace_schema 28974c93956SWalter Erquinigo #include "CommandOptions.inc" 29074c93956SWalter Erquinigo 29174c93956SWalter Erquinigo #pragma mark CommandObjectTraceSchema 29274c93956SWalter Erquinigo 29374c93956SWalter Erquinigo class CommandObjectTraceSchema : public CommandObjectParsed { 29474c93956SWalter Erquinigo public: 29574c93956SWalter Erquinigo class CommandOptions : public Options { 29674c93956SWalter Erquinigo public: 297abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); } 29874c93956SWalter Erquinigo 29974c93956SWalter Erquinigo ~CommandOptions() override = default; 30074c93956SWalter Erquinigo 30174c93956SWalter Erquinigo Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 30274c93956SWalter Erquinigo ExecutionContext *execution_context) override { 30374c93956SWalter Erquinigo Status error; 30474c93956SWalter Erquinigo const int short_option = m_getopt_table[option_idx].val; 30574c93956SWalter Erquinigo 30674c93956SWalter Erquinigo switch (short_option) { 30774c93956SWalter Erquinigo case 'v': { 30874c93956SWalter Erquinigo m_verbose = true; 30974c93956SWalter Erquinigo break; 31074c93956SWalter Erquinigo } 31174c93956SWalter Erquinigo default: 31274c93956SWalter Erquinigo llvm_unreachable("Unimplemented option"); 31374c93956SWalter Erquinigo } 31474c93956SWalter Erquinigo return error; 31574c93956SWalter Erquinigo } 31674c93956SWalter Erquinigo 31774c93956SWalter Erquinigo void OptionParsingStarting(ExecutionContext *execution_context) override { 31874c93956SWalter Erquinigo m_verbose = false; 31974c93956SWalter Erquinigo } 32074c93956SWalter Erquinigo 32174c93956SWalter Erquinigo llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 322984b800aSserge-sans-paille return llvm::ArrayRef(g_trace_schema_options); 32374c93956SWalter Erquinigo } 32474c93956SWalter Erquinigo 32574c93956SWalter Erquinigo bool m_verbose; // Enable verbose logging for debugging purposes. 32674c93956SWalter Erquinigo }; 32774c93956SWalter Erquinigo 32874c93956SWalter Erquinigo CommandObjectTraceSchema(CommandInterpreter &interpreter) 32974c93956SWalter Erquinigo : CommandObjectParsed(interpreter, "trace schema", 33074c93956SWalter Erquinigo "Show the schema of the given trace plugin.", 331ea1f4974SWalter Erquinigo "trace schema <plug-in>. Use the plug-in name " 332c1b07d61SJim Ingham "\"all\" to see all schemas.\n") { 3332d704f4bSjimingham AddSimpleArgumentList(eArgTypeNone); 334c1b07d61SJim Ingham } 33574c93956SWalter Erquinigo 33674c93956SWalter Erquinigo ~CommandObjectTraceSchema() override = default; 33774c93956SWalter Erquinigo 33874c93956SWalter Erquinigo Options *GetOptions() override { return &m_options; } 33974c93956SWalter Erquinigo 34074c93956SWalter Erquinigo protected: 34192d8a28cSPete Lawrence void DoExecute(Args &command, CommandReturnObject &result) override { 34274c93956SWalter Erquinigo Status error; 34374c93956SWalter Erquinigo if (command.empty()) { 3441b1c8e4aSDavid Spickett result.AppendError( 34574c93956SWalter Erquinigo "trace schema cannot be invoked without a plug-in as argument"); 34692d8a28cSPete Lawrence return; 34774c93956SWalter Erquinigo } 34874c93956SWalter Erquinigo 34974c93956SWalter Erquinigo StringRef plugin_name(command[0].c_str()); 350ea1f4974SWalter Erquinigo if (plugin_name == "all") { 351ea1f4974SWalter Erquinigo size_t index = 0; 352ea1f4974SWalter Erquinigo while (true) { 353ea1f4974SWalter Erquinigo StringRef schema = PluginManager::GetTraceSchema(index++); 354ea1f4974SWalter Erquinigo if (schema.empty()) 355ea1f4974SWalter Erquinigo break; 35674c93956SWalter Erquinigo 357ea1f4974SWalter Erquinigo result.AppendMessage(schema); 358ea1f4974SWalter Erquinigo } 35974c93956SWalter Erquinigo } else { 360ea1f4974SWalter Erquinigo if (Expected<StringRef> schemaOrErr = 361ea1f4974SWalter Erquinigo Trace::FindPluginSchema(plugin_name)) 362ea1f4974SWalter Erquinigo result.AppendMessage(*schemaOrErr); 363ea1f4974SWalter Erquinigo else 364*a0dd90ebSAdrian Prantl error = Status::FromError(schemaOrErr.takeError()); 36574c93956SWalter Erquinigo } 36674c93956SWalter Erquinigo 36774c93956SWalter Erquinigo if (error.Success()) { 36874c93956SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult); 36974c93956SWalter Erquinigo } else { 37074c93956SWalter Erquinigo result.AppendErrorWithFormat("%s\n", error.AsCString()); 37174c93956SWalter Erquinigo } 37274c93956SWalter Erquinigo } 37374c93956SWalter Erquinigo 37474c93956SWalter Erquinigo CommandOptions m_options; 37574c93956SWalter Erquinigo }; 37674c93956SWalter Erquinigo 37774c93956SWalter Erquinigo // CommandObjectTrace 37874c93956SWalter Erquinigo 37974c93956SWalter Erquinigo CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter) 38074c93956SWalter Erquinigo : CommandObjectMultiword(interpreter, "trace", 38174c93956SWalter Erquinigo "Commands for loading and using processor " 38274c93956SWalter Erquinigo "trace information.", 38374c93956SWalter Erquinigo "trace [<sub-command-options>]") { 38474c93956SWalter Erquinigo LoadSubCommand("load", 38574c93956SWalter Erquinigo CommandObjectSP(new CommandObjectTraceLoad(interpreter))); 38674c93956SWalter Erquinigo LoadSubCommand("dump", 38774c93956SWalter Erquinigo CommandObjectSP(new CommandObjectTraceDump(interpreter))); 388b532dd54SWalter Erquinigo LoadSubCommand("save", 389b532dd54SWalter Erquinigo CommandObjectSP(new CommandObjectTraceSave(interpreter))); 39074c93956SWalter Erquinigo LoadSubCommand("schema", 39174c93956SWalter Erquinigo CommandObjectSP(new CommandObjectTraceSchema(interpreter))); 39274c93956SWalter Erquinigo } 39374c93956SWalter Erquinigo 39474c93956SWalter Erquinigo CommandObjectTrace::~CommandObjectTrace() = default; 3950b697561SWalter Erquinigo 3960b697561SWalter Erquinigo Expected<CommandObjectSP> CommandObjectTraceProxy::DoGetProxyCommandObject() { 3970b697561SWalter Erquinigo ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP(); 3980b697561SWalter Erquinigo 3990b697561SWalter Erquinigo if (!process_sp) 4000b697561SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 4010b697561SWalter Erquinigo "Process not available."); 4020b697561SWalter Erquinigo if (m_live_debug_session_only && !process_sp->IsLiveDebugSession()) 4030b697561SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 4040b697561SWalter Erquinigo "Process must be alive."); 4050b697561SWalter Erquinigo 406bf9f21a2SWalter Erquinigo if (Expected<TraceSP> trace_sp = process_sp->GetTarget().GetTraceOrCreate()) 4070b697561SWalter Erquinigo return GetDelegateCommand(**trace_sp); 4080b697561SWalter Erquinigo else 4090b697561SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 4100b697561SWalter Erquinigo "Tracing is not supported. %s", 4110b697561SWalter Erquinigo toString(trace_sp.takeError()).c_str()); 4120b697561SWalter Erquinigo } 4130b697561SWalter Erquinigo 4140b697561SWalter Erquinigo CommandObject *CommandObjectTraceProxy::GetProxyCommandObject() { 4150b697561SWalter Erquinigo if (Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) { 4160b697561SWalter Erquinigo m_delegate_sp = *delegate; 4170b697561SWalter Erquinigo m_delegate_error.clear(); 4180b697561SWalter Erquinigo return m_delegate_sp.get(); 4190b697561SWalter Erquinigo } else { 4200b697561SWalter Erquinigo m_delegate_sp.reset(); 4210b697561SWalter Erquinigo m_delegate_error = toString(delegate.takeError()); 4220b697561SWalter Erquinigo return nullptr; 4230b697561SWalter Erquinigo } 4240b697561SWalter Erquinigo } 425