[Lldb-commits] [lldb] c1b4632 - [trace] Add the definition of a TraceExporter plugin

Walter Erquinigo via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 26 18:01:59 PDT 2021


Author: Walter Erquinigo
Date: 2021-07-26T18:01:50-07:00
New Revision: c1b4632528cb405c9ef94cff90bf43afe688a899

URL: https://github.com/llvm/llvm-project/commit/c1b4632528cb405c9ef94cff90bf43afe688a899
DIFF: https://github.com/llvm/llvm-project/commit/c1b4632528cb405c9ef94cff90bf43afe688a899.diff

LOG: [trace] Add the definition of a TraceExporter plugin

Copying from the inline documentation:

```
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.
```

I want to use this to make the code in https://reviews.llvm.org/D105741 a plug-in. I also imagine that there will be more and more exporters being implemented, as an exporter creates something useful out of trace data. And tbh I don't want to keep adding more stuff to the lldb/Target folder.

This is the minimal definition for a TraceExporter plugin. I plan to use this with the following commands:

- thread trace export <plug-in name> [plug-in specific args]
  - This command would support autocompletion of plug-in names
- thread trace export list
  - This command would list the available trace exporter plug-ins

I don't plan to create yet a "process trace export" because it's easier to start analyzing the trace of a given thread than of the entire process. When we need a process-level command, we can implement it.

I also don't plan to force each "export" command implementation to support multiple threads (for example, "thread trace start 1 2 3" or "thread trace start all" operate on many threads simultaneously). The reason is that the format used by the exporter might or might not support multiple threads, so I'm leaving this decision to each trace exporter plug-in.

Differential Revision: https://reviews.llvm.org/D106501

Added: 
    lldb/include/lldb/Target/TraceExporter.h
    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/TraceExporter.cpp

Modified: 
    lldb/include/lldb/Core/PluginManager.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/Target/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
index 42fa953797c5f..be91929c62e13 100644
--- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h
@@ -369,6 +369,28 @@ class PluginManager {
   ///     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);

diff  --git a/lldb/include/lldb/Target/TraceExporter.h b/lldb/include/lldb/Target/TraceExporter.h
new file mode 100644
index 0000000000000..6560b39fd42ea
--- /dev/null
+++ b/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 
diff erent 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

diff  --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 2206f575fb08c..ad5298151e4a4 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -230,6 +230,7 @@ class ThreadSpec;
 class ThreadPostMortemTrace;
 class Trace;
 class TraceCursor;
+class TraceExporter;
 class Type;
 class TypeAndOrName;
 class TypeCategoryImpl;
@@ -441,6 +442,7 @@ typedef std::shared_ptr<lldb_private::ThreadPostMortemTrace>
 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;

diff  --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h
index cdc4dc0dee42a..2ed083ec8ae95 100644
--- a/lldb/include/lldb/lldb-private-interfaces.h
+++ b/lldb/include/lldb/lldb-private-interfaces.h
@@ -113,11 +113,17 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error,
                                            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)

diff  --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 3b58d71048739..7247601b292b0 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1924,13 +1924,38 @@ class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword {
 
 // 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 
diff erent 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 @@ class CommandObjectMultiwordTrace : public CommandObjectMultiword {
                    CommandObjectSP(new CommandObjectTraceStart(interpreter)));
     LoadSubCommand("stop",
                    CommandObjectSP(new CommandObjectTraceStop(interpreter)));
+    LoadSubCommand("export",
+                   CommandObjectSP(new CommandObjectTraceExport(interpreter)));
   }
 
   ~CommandObjectMultiwordTrace() override = default;

diff  --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 207d38938d08f..fcaa868b083ed 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -1076,6 +1076,59 @@ llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
   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;

diff  --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt
index 3da23eca0773e..9181a4e47675f 100644
--- a/lldb/source/Plugins/CMakeLists.txt
+++ b/lldb/source/Plugins/CMakeLists.txt
@@ -20,6 +20,7 @@ add_subdirectory(SymbolFile)
 add_subdirectory(SystemRuntime)
 add_subdirectory(SymbolVendor)
 add_subdirectory(Trace)
+add_subdirectory(TraceExporter)
 add_subdirectory(TypeSystem)
 add_subdirectory(UnwindAssembly)
 

diff  --git a/lldb/source/Plugins/TraceExporter/CMakeLists.txt b/lldb/source/Plugins/TraceExporter/CMakeLists.txt
new file mode 100644
index 0000000000000..7c4019186c9a6
--- /dev/null
+++ b/lldb/source/Plugins/TraceExporter/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(ctf)

diff  --git a/lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt b/lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt
new file mode 100644
index 0000000000000..766cc18b91967
--- /dev/null
+++ b/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)

diff  --git a/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
new file mode 100644
index 0000000000000..3dd4c89e2777a
--- /dev/null
+++ b/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();
+}

diff  --git a/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h b/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
new file mode 100644
index 0000000000000..26b068a8f8c58
--- /dev/null
+++ b/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

diff  --git a/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp b/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
new file mode 100644
index 0000000000000..08bc03d78303a
--- /dev/null
+++ b/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>();
+}

diff  --git a/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h b/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
new file mode 100644
index 0000000000000..8f9e354ab0dd6
--- /dev/null
+++ b/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

diff  --git a/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td b/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
new file mode 100644
index 0000000000000..ce751f148d9fc
--- /dev/null
+++ b/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.">;
+}

diff  --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt
index da026f567d073..2405258bc4166 100644
--- a/lldb/source/Target/CMakeLists.txt
+++ b/lldb/source/Target/CMakeLists.txt
@@ -68,6 +68,7 @@ add_lldb_library(lldbTarget
   ThreadSpec.cpp
   Trace.cpp
   TraceCursor.cpp
+  TraceExporter.cpp
   TraceInstructionDumper.cpp
   UnixSignals.cpp
   UnwindAssembly.cpp

diff  --git a/lldb/source/Target/TraceExporter.cpp b/lldb/source/Target/TraceExporter.cpp
new file mode 100644
index 0000000000000..1a6571dba4a0f
--- /dev/null
+++ b/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);
+}


        


More information about the lldb-commits mailing list