This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc1b4632528cb: [trace] Add the definition of a TraceExporter 
plugin (authored by Walter Erquinigo <wall...@fb.com>).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D106501/new/

https://reviews.llvm.org/D106501

Files:
  lldb/include/lldb/Core/PluginManager.h
  lldb/include/lldb/Target/TraceExporter.h
  lldb/include/lldb/lldb-forward.h
  lldb/include/lldb/lldb-private-interfaces.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Core/PluginManager.cpp
  lldb/source/Plugins/CMakeLists.txt
  lldb/source/Plugins/TraceExporter/CMakeLists.txt
  lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt
  lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
  lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
  lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
  lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
  lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
  lldb/source/Target/CMakeLists.txt
  lldb/source/Target/TraceExporter.cpp

Index: lldb/source/Target/TraceExporter.cpp
===================================================================
--- /dev/null
+++ lldb/source/Target/TraceExporter.cpp
@@ -0,0 +1,32 @@
+//===-- TraceExporter.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 "lldb/Target/TraceExporter.h"
+
+#include "lldb/Core/PluginManager.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+static Error createInvalidPlugInError(StringRef plugin_name) {
+  return createStringError(
+      std::errc::invalid_argument,
+      "no trace expoter plug-in matches the specified type: \"%s\"",
+      plugin_name.data());
+}
+
+Expected<lldb::TraceExporterUP>
+TraceExporter::FindPlugin(llvm::StringRef plugin_name) {
+  ConstString name(plugin_name);
+  if (auto create_callback =
+          PluginManager::GetTraceExporterCreateCallback(name))
+    return create_callback();
+
+  return createInvalidPlugInError(plugin_name);
+}
Index: lldb/source/Target/CMakeLists.txt
===================================================================
--- lldb/source/Target/CMakeLists.txt
+++ lldb/source/Target/CMakeLists.txt
@@ -68,6 +68,7 @@
   ThreadSpec.cpp
   Trace.cpp
   TraceCursor.cpp
+  TraceExporter.cpp
   TraceInstructionDumper.cpp
   UnixSignals.cpp
   UnwindAssembly.cpp
Index: lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
@@ -0,0 +1,9 @@
+include "../../../../source/Commands/OptionsBase.td"
+
+let Command = "thread trace export ctf" in {
+  def thread_trace_export_ctf: Option<"tid", "t">,
+    Group<1>,
+    Arg<"ThreadIndex">,
+    Desc<"Export the trace for the specified thread index. Otherwise, the "
+         "currently selected thread will be used.">;
+}
Index: lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
@@ -0,0 +1,42 @@
+//===-- TraceExporterCTF.h --------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
+#define LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
+
+#include "lldb/Target/TraceExporter.h"
+
+namespace lldb_private {
+namespace ctf {
+
+/// Trace Exporter Plugin that can produce traces in Chrome Trace Format.
+/// Still in development.
+class TraceExporterCTF : public TraceExporter {
+public:
+  ~TraceExporterCTF() override = default;
+
+  /// PluginInterface protocol
+  /// \{
+  static llvm::Expected<lldb::TraceExporterUP> CreateInstance();
+
+  ConstString GetPluginName() override;
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static ConstString GetPluginNameStatic();
+
+  uint32_t GetPluginVersion() override;
+  /// \}
+};
+
+} // namespace ctf
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
Index: lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
@@ -0,0 +1,53 @@
+//===-- TraceExporterCTF.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 "TraceExporterCTF.h"
+
+#include <memory>
+
+#include "CommandObjectThreadTraceExportCTF.h"
+#include "lldb/Core/PluginManager.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::ctf;
+using namespace llvm;
+
+LLDB_PLUGIN_DEFINE(TraceExporterCTF)
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+static CommandObjectSP
+GetThreadTraceExportCommand(CommandInterpreter &interpreter) {
+  return std::make_shared<CommandObjectThreadTraceExportCTF>(interpreter);
+}
+
+void TraceExporterCTF::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                "Chrome Trace Format Exporter", CreateInstance,
+                                GetThreadTraceExportCommand);
+}
+
+void TraceExporterCTF::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString TraceExporterCTF::GetPluginNameStatic() {
+  static ConstString g_name("ctf");
+  return g_name;
+}
+
+ConstString TraceExporterCTF::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t TraceExporterCTF::GetPluginVersion() { return 1; }
+
+Expected<TraceExporterUP> TraceExporterCTF::CreateInstance() {
+  return std::make_unique<TraceExporterCTF>();
+}
Index: lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
@@ -0,0 +1,56 @@
+//===-- CommandObjectThreadTraceExportCTF.h -------------------*- C++ //-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
+
+#include "TraceExporterCTF.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+namespace lldb_private {
+namespace ctf {
+
+class CommandObjectThreadTraceExportCTF : public CommandObjectParsed {
+public:
+  class CommandOptions : public Options {
+  public:
+    CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override;
+
+    void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+    llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+    llvm::Optional<size_t> m_thread_index;
+  };
+
+  CommandObjectThreadTraceExportCTF(CommandInterpreter &interpreter)
+      : CommandObjectParsed(
+            interpreter, "thread trace export ctf",
+            "Export a given thread's trace to Chrome Trace Format",
+            "thread trace export ctf [<ctf-options>]",
+            lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
+                lldb::eCommandProcessMustBeLaunched |
+                lldb::eCommandProcessMustBePaused),
+        m_options() {}
+
+  Options *GetOptions() override { return &m_options; }
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override;
+
+  CommandOptions m_options;
+};
+
+} // namespace ctf
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
Index: lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
@@ -0,0 +1,66 @@
+//===-- CommandObjectThreadTraceExportCTF.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 "CommandObjectThreadTraceExportCTF.h"
+
+#include "lldb/Host/OptionParser.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::ctf;
+using namespace llvm;
+
+// CommandObjectThreadTraceExportCTF
+
+#define LLDB_OPTIONS_thread_trace_export_ctf
+#include "TraceExporterCTFCommandOptions.inc"
+
+Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue(
+    uint32_t option_idx, llvm::StringRef option_arg,
+    ExecutionContext *execution_context) {
+  Status error;
+  const int short_option = m_getopt_table[option_idx].val;
+
+  switch (short_option) {
+  case 't': {
+    int64_t thread_index;
+    if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) ||
+        thread_index < 0)
+      error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+                                     option_arg.str().c_str());
+    else
+      m_thread_index = thread_index;
+    break;
+  }
+  default:
+    llvm_unreachable("Unimplemented option");
+  }
+  return error;
+}
+
+void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting(
+    ExecutionContext *execution_context) {
+  m_thread_index = None;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() {
+  return llvm::makeArrayRef(g_thread_trace_export_ctf_options);
+}
+
+bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
+                                                  CommandReturnObject &result) {
+  Stream &s = result.GetOutputStream();
+  // TODO: create an actual instance of the exporter and invoke it
+  if (m_options.m_thread_index)
+    s.Printf("got thread index %d\n", (int)m_options.m_thread_index.getValue());
+  else
+    s.Printf("didn't get a thread index\n");
+
+  return result.Succeeded();
+}
Index: lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt
@@ -0,0 +1,17 @@
+lldb_tablegen(TraceExporterCTFCommandOptions.inc -gen-lldb-option-defs
+  SOURCE TraceExporterCTFOptions.td
+  TARGET TraceExporterCTFOptionsGen)
+
+add_lldb_library(lldbPluginTraceExporterCTF PLUGIN
+CommandObjectThreadTraceExportCTF.cpp
+  TraceExporterCTF.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbSymbol
+    lldbTarget
+  LINK_COMPONENTS
+    Support
+  )
+
+add_dependencies(lldbPluginTraceExporterCTF TraceExporterCTFOptionsGen)
Index: lldb/source/Plugins/TraceExporter/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/TraceExporter/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(ctf)
Index: lldb/source/Plugins/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/CMakeLists.txt
+++ lldb/source/Plugins/CMakeLists.txt
@@ -20,6 +20,7 @@
 add_subdirectory(SystemRuntime)
 add_subdirectory(SymbolVendor)
 add_subdirectory(Trace)
+add_subdirectory(TraceExporter)
 add_subdirectory(TypeSystem)
 add_subdirectory(UnwindAssembly)
 
Index: lldb/source/Core/PluginManager.cpp
===================================================================
--- lldb/source/Core/PluginManager.cpp
+++ lldb/source/Core/PluginManager.cpp
@@ -1076,6 +1076,59 @@
   return llvm::StringRef();
 }
 
+#pragma mark TraceExporter
+
+struct TraceExporterInstance
+    : public PluginInstance<TraceExporterCreateInstance> {
+  TraceExporterInstance(
+      ConstString name, std::string description,
+      TraceExporterCreateInstance create_instance,
+      ThreadTraceExportCommandCreator create_thread_trace_export_command)
+      : PluginInstance<TraceExporterCreateInstance>(
+            name, std::move(description), create_instance),
+        create_thread_trace_export_command(create_thread_trace_export_command) {
+  }
+
+  ThreadTraceExportCommandCreator create_thread_trace_export_command;
+};
+
+typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
+
+static TraceExporterInstances &GetTraceExporterInstances() {
+  static TraceExporterInstances g_instances;
+  return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+    ConstString name, const char *description,
+    TraceExporterCreateInstance create_callback,
+    ThreadTraceExportCommandCreator create_thread_trace_export_command) {
+  return GetTraceExporterInstances().RegisterPlugin(
+      name, description, create_callback, create_thread_trace_export_command);
+}
+
+TraceExporterCreateInstance
+PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) {
+  return GetTraceExporterInstances().GetCallbackForName(plugin_name);
+}
+
+bool PluginManager::UnregisterPlugin(
+    TraceExporterCreateInstance create_callback) {
+  return GetTraceExporterInstances().UnregisterPlugin(create_callback);
+}
+
+ThreadTraceExportCommandCreator
+PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
+  if (TraceExporterInstance *instance =
+          GetTraceExporterInstances().GetInstanceAtIndex(index))
+    return instance->create_thread_trace_export_command;
+  return nullptr;
+}
+
+const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
+  return GetTraceExporterInstances().GetNameAtIndex(index);
+}
+
 #pragma mark UnwindAssembly
 
 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
Index: lldb/source/Commands/CommandObjectThread.cpp
===================================================================
--- lldb/source/Commands/CommandObjectThread.cpp
+++ lldb/source/Commands/CommandObjectThread.cpp
@@ -1924,13 +1924,38 @@
 
 // Next are the subcommands of CommandObjectMultiwordTrace
 
+// CommandObjectTraceExport
+
+class CommandObjectTraceExport : public CommandObjectMultiword {
+public:
+  CommandObjectTraceExport(CommandInterpreter &interpreter)
+      : CommandObjectMultiword(
+            interpreter, "trace thread export",
+            "Commands for exporting traces of the threads in the current "
+            "process to different formats.",
+            "thread trace export <export-plugin> [<subcommand objects>]") {
+
+    for (uint32_t i = 0; true; i++) {
+      if (const char *plugin_name =
+              PluginManager::GetTraceExporterPluginNameAtIndex(i)) {
+        if (ThreadTraceExportCommandCreator command_creator =
+                PluginManager::GetThreadTraceExportCommandCreatorAtIndex(i)) {
+          LoadSubCommand(plugin_name, command_creator(interpreter));
+        }
+      } else {
+        break;
+      }
+    }
+  }
+};
+
 // CommandObjectTraceStart
 
 class CommandObjectTraceStart : public CommandObjectTraceProxy {
 public:
   CommandObjectTraceStart(CommandInterpreter &interpreter)
       : CommandObjectTraceProxy(
-            /*live_debug_session_only*/ true, interpreter, "thread trace start",
+            /*live_debug_session_only=*/true, interpreter, "thread trace start",
             "Start tracing threads with the corresponding trace "
             "plug-in for the current process.",
             "thread trace start [<trace-options>]") {}
@@ -2248,6 +2273,8 @@
                    CommandObjectSP(new CommandObjectTraceStart(interpreter)));
     LoadSubCommand("stop",
                    CommandObjectSP(new CommandObjectTraceStop(interpreter)));
+    LoadSubCommand("export",
+                   CommandObjectSP(new CommandObjectTraceExport(interpreter)));
   }
 
   ~CommandObjectMultiwordTrace() override = default;
Index: lldb/include/lldb/lldb-private-interfaces.h
===================================================================
--- lldb/include/lldb/lldb-private-interfaces.h
+++ lldb/include/lldb/lldb-private-interfaces.h
@@ -113,11 +113,17 @@
                                            const char *repl_options);
 typedef int (*ComparisonFunction)(const void *, const void *);
 typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
+/// Trace
+/// \{
 typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)(
     const llvm::json::Value &trace_session_file,
     llvm::StringRef session_file_dir, lldb_private::Debugger &debugger);
 typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForLiveProcess)(
     Process &process);
+typedef llvm::Expected<lldb::TraceExporterUP> (*TraceExporterCreateInstance)();
+typedef lldb::CommandObjectSP (*ThreadTraceExportCommandCreator)(
+    CommandInterpreter &interpreter);
+/// \}
 } // namespace lldb_private
 
 #endif // #if defined(__cplusplus)
Index: lldb/include/lldb/lldb-forward.h
===================================================================
--- lldb/include/lldb/lldb-forward.h
+++ lldb/include/lldb/lldb-forward.h
@@ -230,6 +230,7 @@
 class ThreadPostMortemTrace;
 class Trace;
 class TraceCursor;
+class TraceExporter;
 class Type;
 class TypeAndOrName;
 class TypeCategoryImpl;
@@ -441,6 +442,7 @@
 typedef std::weak_ptr<lldb_private::ThreadPlan> ThreadPlanWP;
 typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
 typedef std::shared_ptr<lldb_private::Trace> TraceSP;
+typedef std::unique_ptr<lldb_private::TraceExporter> TraceExporterUP;
 typedef std::unique_ptr<lldb_private::TraceCursor> TraceCursorUP;
 typedef std::shared_ptr<lldb_private::Type> TypeSP;
 typedef std::weak_ptr<lldb_private::Type> TypeWP;
Index: lldb/include/lldb/Target/TraceExporter.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Target/TraceExporter.h
@@ -0,0 +1,42 @@
+//===-- TraceExporter.h -----------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_TRACE_EXPORTER_H
+#define LLDB_TARGET_TRACE_EXPORTER_H
+
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+
+/// \class TraceExporter TraceExporter.h "lldb/Target/TraceExporter.h"
+/// A plug-in interface definition class for trace exporters.
+///
+/// Trace exporter plug-ins operate on traces, converting the trace data
+/// provided by an \a lldb_private::TraceCursor into a different format that can
+/// be digested by other tools, e.g. Chrome Trace Event Profiler.
+///
+/// Trace exporters are supposed to operate on an architecture-agnostic fashion,
+/// as a TraceCursor, which feeds the data, hides the actual trace technology
+/// being used.
+class TraceExporter : public PluginInterface {
+public:
+  /// Create an instance of a trace exporter plugin given its name.
+  ///
+  /// \param[in] plugin_Name
+  ///     Plug-in name to search.
+  ///
+  /// \return
+  ///     A \a TraceExporterUP instance, or an \a llvm::Error if the plug-in
+  ///     name doesn't match any registered plug-ins.
+  static llvm::Expected<lldb::TraceExporterUP>
+  FindPlugin(llvm::StringRef plugin_name);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_TRACE_EXPORTER_H
Index: lldb/include/lldb/Core/PluginManager.h
===================================================================
--- lldb/include/lldb/Core/PluginManager.h
+++ lldb/include/lldb/Core/PluginManager.h
@@ -369,6 +369,28 @@
   ///     number plugins, otherwise the actual schema is returned.
   static llvm::StringRef GetTraceSchema(size_t index);
 
+  // TraceExporter
+
+  /// \param[in] create_thread_trace_export_command
+  ///     This callback is used to create a CommandObject that will be listed
+  ///     under "thread trace export". Can be \b null.
+  static bool RegisterPlugin(
+      ConstString name, const char *description,
+      TraceExporterCreateInstance create_callback,
+      ThreadTraceExportCommandCreator create_thread_trace_export_command);
+
+  static TraceExporterCreateInstance
+  GetTraceExporterCreateCallback(ConstString plugin_name);
+
+  static bool UnregisterPlugin(TraceExporterCreateInstance create_callback);
+
+  static const char *GetTraceExporterPluginNameAtIndex(uint32_t index);
+
+  /// Return the callback used to create the CommandObject that will be listed
+  /// under "thread trace export". Can be \b null.
+  static ThreadTraceExportCommandCreator
+  GetThreadTraceExportCommandCreatorAtIndex(uint32_t index);
+
   // UnwindAssembly
   static bool RegisterPlugin(ConstString name, const char *description,
                              UnwindAssemblyCreateInstance create_callback);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to