diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -369,6 +369,19 @@ /// number plugins, otherwise the actual schema is returned. static llvm::StringRef GetTraceSchema(size_t index); + // TraceExporter + static bool RegisterPlugin(ConstString name, const char *description, + TraceExporterCreateInstance create_callback); + + static bool UnregisterPlugin(TraceExporterCreateInstance create_callback); + + static TraceExporterCreateInstance + GetTraceExporterCreateCallback(ConstString plugin_name); + + static const char *GetTraceExporterPluginDescriptionAtIndex(uint32_t index); + + static const char *GetTraceExporterPluginNameAtIndex(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 --- /dev/null +++ b/lldb/include/lldb/Target/TraceExporter.h @@ -0,0 +1,46 @@ +//===-- 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 TraceExporterSP instance, or an \a llvm::Error if the plug-in + /// name doesn't match any registered plug-ins. + static llvm::Expected + FindPlugin(llvm::StringRef plugin_name); + + /// Get the command handle for the "thread trace export" command. + virtual lldb::CommandObjectSP + GetThreadTraceExportCommand(CommandInterpreter &interpreter) = 0; +}; + +} // 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 --- a/lldb/include/lldb/lldb-forward.h +++ b/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 ThreadPlanWP; typedef std::shared_ptr ThreadPlanTracerSP; typedef std::shared_ptr TraceSP; +typedef std::shared_ptr TraceExporterSP; typedef std::unique_ptr TraceCursorUP; typedef std::shared_ptr TypeSP; typedef std::weak_ptr TypeWP; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -118,6 +118,7 @@ llvm::StringRef session_file_dir, lldb_private::Debugger &debugger); typedef llvm::Expected (*TraceCreateInstanceForLiveProcess)( Process &process); +typedef llvm::Expected (*TraceExporterCreateInstance)(); } // namespace lldb_private #endif // #if defined(__cplusplus) diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -1076,6 +1076,37 @@ return llvm::StringRef(); } +#pragma mark TraceExporter + +typedef PluginInstance TraceExporterInstance; +typedef PluginInstances TraceExporterInstances; + +static TraceExporterInstances &GetTraceExporterInstances() { + static TraceExporterInstances g_instances; + return g_instances; +} + +bool PluginManager::RegisterPlugin( + ConstString name, const char *description, + TraceExporterCreateInstance create_callback) { + return GetTraceExporterInstances().RegisterPlugin(name, description, + create_callback); +} + +bool PluginManager::UnregisterPlugin( + TraceExporterCreateInstance create_callback) { + return GetTraceExporterInstances().UnregisterPlugin(create_callback); +} + +const char * +PluginManager::GetTraceExporterPluginDescriptionAtIndex(uint32_t index) { + return GetTraceExporterInstances().GetDescriptionAtIndex(index); +} + +const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { + return GetTraceExporterInstances().GetNameAtIndex(index); +} + #pragma mark UnwindAssembly typedef PluginInstance UnwindAssemblyInstance; diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -68,6 +68,7 @@ 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 --- /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 +TraceExporter::FindPlugin(llvm::StringRef plugin_name) { + ConstString name(plugin_name); + if (auto create_callback = + PluginManager::GetTraceExporterCreateCallback(name)) + return create_callback(); + + return createInvalidPlugInError(plugin_name); +}