diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 | 
| commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
| tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp | |
| parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
Diffstat (limited to 'contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp')
| -rw-r--r-- | contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp | 305 | 
1 files changed, 305 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp new file mode 100644 index 000000000000..170630b85b2e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp @@ -0,0 +1,305 @@ +//===-- CommandObjectTrace.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectTrace.h" + +#include "llvm/Support/JSON.h" +#include "llvm/Support/MemoryBuffer.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Host/OptionParser.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupFormat.h" +#include "lldb/Interpreter/OptionValueBoolean.h" +#include "lldb/Interpreter/OptionValueLanguage.h" +#include "lldb/Interpreter/OptionValueString.h" +#include "lldb/Interpreter/Options.h" +#include "lldb/Target/Trace.h" + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; + +// CommandObjectTraceLoad +#define LLDB_OPTIONS_trace_load +#include "CommandOptions.inc" + +#pragma mark CommandObjectTraceLoad + +class CommandObjectTraceLoad : public CommandObjectParsed { +public: +  class CommandOptions : public Options { +  public: +    CommandOptions() : Options() { OptionParsingStarting(nullptr); } + +    ~CommandOptions() override = default; + +    Status SetOptionValue(uint32_t option_idx, StringRef option_arg, +                          ExecutionContext *execution_context) override { +      Status error; +      const int short_option = m_getopt_table[option_idx].val; + +      switch (short_option) { +      case 'v': { +        m_verbose = true; +        break; +      } +      default: +        llvm_unreachable("Unimplemented option"); +      } +      return error; +    } + +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      m_verbose = false; +    } + +    ArrayRef<OptionDefinition> GetDefinitions() override { +      return makeArrayRef(g_trace_load_options); +    } + +    bool m_verbose; // Enable verbose logging for debugging purposes. +  }; + +  CommandObjectTraceLoad(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "trace load", +                            "Load a processor trace session from a JSON file.", +                            "trace load"), +        m_options() {} + +  ~CommandObjectTraceLoad() override = default; + +  Options *GetOptions() override { return &m_options; } + +protected: +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    if (command.size() != 1) { +      result.AppendError( +          "a single path to a JSON file containing a trace session" +          "is required"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } + +    auto end_with_failure = [&result](llvm::Error err) -> bool { +      result.AppendErrorWithFormat("%s\n", +                                   llvm::toString(std::move(err)).c_str()); +      result.SetStatus(eReturnStatusFailed); +      return false; +    }; + +    FileSpec json_file(command[0].ref()); + +    auto buffer_or_error = llvm::MemoryBuffer::getFile(json_file.GetPath()); +    if (!buffer_or_error) { +      return end_with_failure(llvm::createStringError( +          std::errc::invalid_argument, "could not open input file: %s - %s.", +          json_file.GetPath().c_str(), +          buffer_or_error.getError().message().c_str())); +    } + +    llvm::Expected<json::Value> session_file = +        json::parse(buffer_or_error.get()->getBuffer().str()); +    if (!session_file) +      return end_with_failure(session_file.takeError()); + +    if (Expected<lldb::TraceSP> traceOrErr = +            Trace::FindPlugin(GetDebugger(), *session_file, +                              json_file.GetDirectory().AsCString())) { +      lldb::TraceSP trace_sp = traceOrErr.get(); +      if (m_options.m_verbose) +        result.AppendMessageWithFormat("loading trace with plugin %s\n", +                                       trace_sp->GetPluginName().AsCString()); +    } else +      return end_with_failure(traceOrErr.takeError()); + +    result.SetStatus(eReturnStatusSuccessFinishResult); +    return true; +  } + +  CommandOptions m_options; +}; + +// CommandObjectTraceDump +#define LLDB_OPTIONS_trace_dump +#include "CommandOptions.inc" + +#pragma mark CommandObjectTraceDump + +class CommandObjectTraceDump : public CommandObjectParsed { +public: +  class CommandOptions : public Options { +  public: +    CommandOptions() : Options() { OptionParsingStarting(nullptr); } + +    ~CommandOptions() override = default; + +    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 'v': { +        m_verbose = true; +        break; +      } +      default: +        llvm_unreachable("Unimplemented option"); +      } +      return error; +    } + +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      m_verbose = false; +    } + +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override { +      return llvm::makeArrayRef(g_trace_dump_options); +    } + +    bool m_verbose; // Enable verbose logging for debugging purposes. +  }; + +  CommandObjectTraceDump(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "trace dump", +                            "Dump the loaded processor trace data.", +                            "trace dump"), +        m_options() {} + +  ~CommandObjectTraceDump() override = default; + +  Options *GetOptions() override { return &m_options; } + +protected: +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    Status error; +    // TODO: fill in the dumping code here! +    if (error.Success()) { +      result.SetStatus(eReturnStatusSuccessFinishResult); +    } else { +      result.AppendErrorWithFormat("%s\n", error.AsCString()); +      result.SetStatus(eReturnStatusFailed); +    } +    return result.Succeeded(); +  } + +  CommandOptions m_options; +}; + +// CommandObjectTraceSchema +#define LLDB_OPTIONS_trace_schema +#include "CommandOptions.inc" + +#pragma mark CommandObjectTraceSchema + +class CommandObjectTraceSchema : public CommandObjectParsed { +public: +  class CommandOptions : public Options { +  public: +    CommandOptions() : Options() { OptionParsingStarting(nullptr); } + +    ~CommandOptions() override = default; + +    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 'v': { +        m_verbose = true; +        break; +      } +      default: +        llvm_unreachable("Unimplemented option"); +      } +      return error; +    } + +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      m_verbose = false; +    } + +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override { +      return llvm::makeArrayRef(g_trace_schema_options); +    } + +    bool m_verbose; // Enable verbose logging for debugging purposes. +  }; + +  CommandObjectTraceSchema(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "trace schema", +                            "Show the schema of the given trace plugin.", +                            "trace schema <plug-in>. Use the plug-in name " +                            "\"all\" to see all schemas.\n"), +        m_options() {} + +  ~CommandObjectTraceSchema() override = default; + +  Options *GetOptions() override { return &m_options; } + +protected: +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    Status error; +    if (command.empty()) { +      result.SetError( +          "trace schema cannot be invoked without a plug-in as argument"); +      return false; +    } + +    StringRef plugin_name(command[0].c_str()); +    if (plugin_name == "all") { +      size_t index = 0; +      while (true) { +        StringRef schema = PluginManager::GetTraceSchema(index++); +        if (schema.empty()) +          break; + +        result.AppendMessage(schema); +      } +    } else { +      if (Expected<StringRef> schemaOrErr = +              Trace::FindPluginSchema(plugin_name)) +        result.AppendMessage(*schemaOrErr); +      else +        error = schemaOrErr.takeError(); +    } + +    if (error.Success()) { +      result.SetStatus(eReturnStatusSuccessFinishResult); +    } else { +      result.AppendErrorWithFormat("%s\n", error.AsCString()); +      result.SetStatus(eReturnStatusFailed); +    } +    return result.Succeeded(); +  } + +  CommandOptions m_options; +}; + +// CommandObjectTrace + +CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter) +    : CommandObjectMultiword(interpreter, "trace", +                             "Commands for loading and using processor " +                             "trace information.", +                             "trace [<sub-command-options>]") { +  LoadSubCommand("load", +                 CommandObjectSP(new CommandObjectTraceLoad(interpreter))); +  LoadSubCommand("dump", +                 CommandObjectSP(new CommandObjectTraceDump(interpreter))); +  LoadSubCommand("schema", +                 CommandObjectSP(new CommandObjectTraceSchema(interpreter))); +} + +CommandObjectTrace::~CommandObjectTrace() = default;  | 
