[Lldb-commits] [lldb] 8a203bb - [trace] rename ThreadIntelPT into TraceTrace

Walter Erquinigo via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 19 15:15:09 PDT 2020


Author: Walter Erquinigo
Date: 2020-10-19T15:15:02-07:00
New Revision: 8a203bb22d161d23c6b1195f85ae025e87f03bae

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

LOG: [trace] rename ThreadIntelPT into TraceTrace

Renamed ThreadIntelPT to TreaceThread, making it a top-level class. I noticed that this class can and shuld work for any trace plugin and there's nothing intel-pt specific in it.
With that TraceThread change, I was able to move most of the json file parsing logic to the base class TraceSessionFileParser, which makes adding new plug-ins easier.

This originally was part of https://reviews.llvm.org/D89283

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

Added: 
    lldb/include/lldb/Target/ProcessTrace.h
    lldb/include/lldb/Target/ThreadTrace.h
    lldb/source/Target/ProcessTrace.cpp
    lldb/source/Target/ThreadTrace.cpp

Modified: 
    lldb/include/lldb/Target/TraceSessionFileParser.h
    lldb/include/lldb/lldb-forward.h
    lldb/source/API/SystemInitializerFull.cpp
    lldb/source/Plugins/Process/CMakeLists.txt
    lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
    lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
    lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
    lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
    lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
    lldb/source/Target/CMakeLists.txt
    lldb/source/Target/TraceSessionFileParser.cpp

Removed: 
    lldb/source/Plugins/Process/Trace/CMakeLists.txt
    lldb/source/Plugins/Process/Trace/ProcessTrace.cpp
    lldb/source/Plugins/Process/Trace/ProcessTrace.h
    lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.cpp
    lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.h


################################################################################
diff  --git a/lldb/source/Plugins/Process/Trace/ProcessTrace.h b/lldb/include/lldb/Target/ProcessTrace.h
similarity index 90%
rename from lldb/source/Plugins/Process/Trace/ProcessTrace.h
rename to lldb/include/lldb/Target/ProcessTrace.h
index 450aa1e91d8f..d5a052c1d73b 100644
--- a/lldb/source/Plugins/Process/Trace/ProcessTrace.h
+++ b/lldb/include/lldb/Target/ProcessTrace.h
@@ -6,22 +6,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_TRACE_PROCESSTRACE_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_TRACE_PROCESSTRACE_H
+#ifndef LLDB_TARGET_PROCESSTRACE_H
+#define LLDB_TARGET_PROCESSTRACE_H
 
 #include "lldb/Target/Process.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/Status.h"
 
 namespace lldb_private {
-namespace process_trace {
 
 class ProcessTrace : public Process {
 public:
-  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
-                                        lldb::ListenerSP listener_sp,
-                                        const FileSpec *crash_file_path);
-
   static void Initialize();
 
   static void Terminate();
@@ -78,9 +73,13 @@ class ProcessTrace : public Process {
 
   bool UpdateThreadList(ThreadList &old_thread_list,
                         ThreadList &new_thread_list) override;
+
+private:
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener_sp,
+                                        const FileSpec *crash_file_path);
 };
 
-} // namespace process_trace
 } // namespace lldb_private
 
-#endif // LLDB_SOURCE_PLUGINS_PROCESS_TRACE_PROCESSTRACE_H
+#endif // LLDB_TARGET_PROCESSTRACE_H

diff  --git a/lldb/include/lldb/Target/ThreadTrace.h b/lldb/include/lldb/Target/ThreadTrace.h
new file mode 100644
index 000000000000..a32b33867c26
--- /dev/null
+++ b/lldb/include/lldb/Target/ThreadTrace.h
@@ -0,0 +1,61 @@
+//===-- ThreadTrace.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_THREADTRACE_H
+#define LLDB_TARGET_THREADTRACE_H
+
+#include "lldb/Target/Thread.h"
+
+namespace lldb_private {
+
+/// \class ThreadTrace ThreadTrace.h
+///
+/// Thread implementation used for representing threads gotten from trace
+/// session files, which are similar to threads from core files.
+///
+/// See \a TraceSessionFileParser for more information regarding trace session
+/// files.
+class ThreadTrace : public Thread {
+public:
+  /// \param[in] process
+  ///     The process who owns this thread.
+  ///
+  /// \param[in] tid
+  ///     The tid of this thread.
+  ///
+  /// \param[in] trace_file.
+  ///     The file that contains the list of instructions that were traced when
+  ///     this thread was being executed.
+  ThreadTrace(Process &process, lldb::tid_t tid, const FileSpec &trace_file)
+      : Thread(process, tid), m_trace_file(trace_file) {}
+
+  void RefreshStateAfterStop() override;
+
+  lldb::RegisterContextSP GetRegisterContext() override;
+
+  lldb::RegisterContextSP
+  CreateRegisterContextForFrame(StackFrame *frame) override;
+
+  /// \return
+  ///   The trace file of this thread.
+  const FileSpec &GetTraceFile() const;
+
+protected:
+  bool CalculateStopInfo() override;
+
+  lldb::RegisterContextSP m_thread_reg_ctx_sp;
+
+private:
+  FileSpec m_trace_file;
+};
+
+typedef std::shared_ptr<ThreadTrace> ThreadTraceSP;
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_THREADTRACE_H

diff  --git a/lldb/include/lldb/Target/TraceSessionFileParser.h b/lldb/include/lldb/Target/TraceSessionFileParser.h
index 4bcce9db8406..52cc27c1a485 100644
--- a/lldb/include/lldb/Target/TraceSessionFileParser.h
+++ b/lldb/include/lldb/Target/TraceSessionFileParser.h
@@ -11,7 +11,7 @@
 
 #include "llvm/Support/JSON.h"
 
-#include "lldb/lldb-private.h"
+#include "lldb/Target/ThreadTrace.h"
 
 namespace lldb_private {
 
@@ -53,17 +53,28 @@ class TraceSessionFileParser {
     std::string type;
   };
 
+  struct JSONTraceSessionBase {
+    std::vector<JSONProcess> processes;
+  };
+
   /// The trace plug-in implementation should provide its own TPluginSettings,
   /// which corresponds to the "trace" section of the schema.
-  template <class TPluginSettings> struct JSONTraceSession {
-    std::vector<JSONProcess> processes;
+  template <class TPluginSettings>
+  struct JSONTraceSession : JSONTraceSessionBase {
     TPluginSettings trace;
   };
   /// \}
 
-  TraceSessionFileParser(llvm::StringRef session_file_dir,
+  /// Helper struct holding the objects created when parsing a process
+  struct ParsedProcess {
+    lldb::TargetSP target_sp;
+    std::vector<ThreadTraceSP> threads;
+  };
+
+  TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir,
                          llvm::StringRef schema)
-      : m_session_file_dir(session_file_dir), m_schema(schema) {}
+      : m_debugger(debugger), m_session_file_dir(session_file_dir),
+        m_schema(schema) {}
 
   /// Build the full schema for a Trace plug-in.
   ///
@@ -75,11 +86,28 @@ class TraceSessionFileParser {
   ///   specific attributes.
   static std::string BuildSchema(llvm::StringRef plugin_schema);
 
+  /// Parse the fields common to all trace session schemas.
+  ///
+  /// \param[in] session
+  ///     The session json objects already deserialized.
+  ///
+  /// \return
+  ///     A list of \a ParsedProcess containing all threads and targets created
+  ///     during the parsing, or an error in case of failures. In case of
+  ///     errors, no side effects are produced.
+  llvm::Expected<std::vector<ParsedProcess>>
+  ParseCommonSessionFile(const JSONTraceSessionBase &session);
+
 protected:
   /// Resolve non-absolute paths relative to the session file folder. It
   /// modifies the given file_spec.
   void NormalizePath(lldb_private::FileSpec &file_spec);
 
+  ThreadTraceSP ParseThread(lldb::ProcessSP &process_sp,
+                            const JSONThread &thread);
+
+  llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
+
   llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module);
 
   /// Create a user-friendly error message upon a JSON-parsing failure using the
@@ -96,6 +124,7 @@ class TraceSessionFileParser {
   llvm::Error CreateJSONError(llvm::json::Path::Root &root,
                               const llvm::json::Value &value);
 
+  Debugger &m_debugger;
   std::string m_session_file_dir;
   llvm::StringRef m_schema;
 };
@@ -125,6 +154,11 @@ bool fromJSON(const Value &value,
                   &plugin_settings,
               Path path);
 
+bool fromJSON(
+    const Value &value,
+    lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session,
+    Path path);
+
 template <class TPluginSettings>
 bool fromJSON(
     const Value &value,
@@ -133,7 +167,10 @@ bool fromJSON(
     Path path) {
   ObjectMapper o(value, path);
   return o && o.map("trace", session.trace) &&
-         o.map("processes", session.processes);
+         fromJSON(value,
+                  (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &)
+                      session,
+                  path);
 }
 
 } // namespace json

diff  --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index d7f476af8f0f..a297a928a3f4 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -226,6 +226,7 @@ class ThreadPlanStepRange;
 class ThreadPlanStepThrough;
 class ThreadPlanTracer;
 class ThreadSpec;
+class ThreadTrace;
 class Trace;
 class TraceSessionFileParser;
 class TraceOptions;

diff  --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp
index 7f95e7acf62a..a9723f7547b9 100644
--- a/lldb/source/API/SystemInitializerFull.cpp
+++ b/lldb/source/API/SystemInitializerFull.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Initialization/SystemInitializerCommon.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/ProcessTrace.h"
 #include "lldb/Utility/Timer.h"
 #include "llvm/Support/TargetSelect.h"
 
@@ -45,6 +46,9 @@ llvm::Error SystemInitializerFull::Initialize() {
 #define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p);
 #include "Plugins/Plugins.def"
 
+  // Initialize plug-ins in core LLDB
+  ProcessTrace::Initialize();
+
   // Scan for any system or user LLDB plug-ins
   PluginManager::Initialize();
 
@@ -61,6 +65,9 @@ void SystemInitializerFull::Terminate() {
 
   Debugger::SettingsTerminate();
 
+  // Terminate plug-ins in core LLDB
+  ProcessTrace::Terminate();
+
   // Terminate and unload and loaded system or user LLDB plug-ins
   PluginManager::Terminate();
 

diff  --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt
index a028793e32f3..91f20ec22ac5 100644
--- a/lldb/source/Plugins/Process/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/CMakeLists.txt
@@ -18,4 +18,3 @@ add_subdirectory(Utility)
 add_subdirectory(elf-core)
 add_subdirectory(mach-core)
 add_subdirectory(minidump)
-add_subdirectory(Trace)

diff  --git a/lldb/source/Plugins/Process/Trace/CMakeLists.txt b/lldb/source/Plugins/Process/Trace/CMakeLists.txt
deleted file mode 100644
index 10a5c60b112b..000000000000
--- a/lldb/source/Plugins/Process/Trace/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginProcessTrace PLUGIN
-  ProcessTrace.cpp
-
-  LINK_LIBS
-    lldbCore
-    lldbTarget
-    lldbUtility
-    lldbPluginProcessUtility
-  LINK_COMPONENTS
-    BinaryFormat
-    Object
-    Support
-  )

diff  --git a/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt b/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
index 5b3091926d37..fabdb39c34be 100644
--- a/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
+++ b/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
@@ -12,7 +12,6 @@ find_library(LIBIPT_LIBRARY ipt PATHS ${LIBIPT_LIBRARY_PATH} REQUIRED)
 add_lldb_library(lldbPluginTraceIntelPT PLUGIN
   TraceIntelPT.cpp
   TraceIntelPTSessionFileParser.cpp
-  ThreadIntelPT.cpp
 
   LINK_LIBS
     lldbCore

diff  --git a/lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.h b/lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.h
deleted file mode 100644
index ad6b772e2b28..000000000000
--- a/lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- ThreadIntelPT.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_THREADINTELPT_H
-#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_THREADINTELPT_H
-
-#include "lldb/Target/Thread.h"
-
-namespace lldb_private {
-namespace trace_intel_pt {
-
-class ThreadIntelPT : public Thread {
-public:
-  /// Create an Intel PT-traced thread.
-  ///
-  /// \param[in] process
-  ///     The process that owns this thread.
-  ///
-  /// \param[in] tid
-  ///     The thread id of this thread.
-  ///
-  /// \param[in] trace_file
-  ///     The trace file for this thread.
-  ///
-  /// \param[in] pt_cpu
-  ///     The Intel CPU information required to decode the \a trace_file.
-  ThreadIntelPT(Process &process, lldb::tid_t tid, const FileSpec &trace_file)
-      : Thread(process, tid), m_trace_file(trace_file) {}
-
-  void RefreshStateAfterStop() override;
-
-  lldb::RegisterContextSP GetRegisterContext() override;
-
-  lldb::RegisterContextSP
-  CreateRegisterContextForFrame(StackFrame *frame) override;
-
-protected:
-  bool CalculateStopInfo() override;
-
-  lldb::RegisterContextSP m_thread_reg_ctx_sp;
-
-private:
-  FileSpec m_trace_file;
-};
-
-} // namespace trace_intel_pt
-} // namespace lldb_private
-
-#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_THREADINTELPT_H

diff  --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
index e2b24672b086..ef45fdde0fd0 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -10,7 +10,9 @@
 
 #include "TraceIntelPTSessionFileParser.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadTrace.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -56,11 +58,11 @@ TraceIntelPT::CreateInstance(const json::Value &trace_session_file,
       .Parse();
 }
 
-TraceSP TraceIntelPT::CreateInstance(const pt_cpu &pt_cpu,
-                                     const std::vector<TargetSP> &targets) {
-  TraceSP trace_instance(new TraceIntelPT(pt_cpu, targets));
-  for (const TargetSP &target_sp : targets)
-    target_sp->SetTrace(trace_instance);
-
-  return trace_instance;
+TraceIntelPT::TraceIntelPT(
+    const pt_cpu &pt_cpu,
+    const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads)
+    : m_pt_cpu(pt_cpu) {
+  for (const std::shared_ptr<ThreadTrace> &thread : traced_threads)
+    m_trace_threads.emplace(
+        std::make_pair(thread->GetProcess()->GetID(), thread->GetID()), thread);
 }

diff  --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
index bf34d89a347e..39f3db4d434b 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -52,21 +52,6 @@ class TraceIntelPT : public Trace {
   CreateInstance(const llvm::json::Value &trace_session_file,
                  llvm::StringRef session_file_dir, Debugger &debugger);
 
-  /// Create an instance of this class.
-  ///
-  /// \param[in] pt_cpu
-  ///     The libipt.h cpu information needed for decoding correctling the
-  ///     traces.
-  ///
-  /// \param[in] targets
-  ///     The list of targets to associate with this trace instance
-  ///
-  /// \return
-  ///     An intel-pt trace instance.
-  static lldb::TraceSP
-  CreateInstance(const pt_cpu &pt_cpu,
-                 const std::vector<lldb::TargetSP> &targets);
-
   static ConstString GetPluginNameStatic();
 
   uint32_t GetPluginVersion() override;
@@ -75,14 +60,17 @@ class TraceIntelPT : public Trace {
   llvm::StringRef GetSchema() override;
 
 private:
-  TraceIntelPT(const pt_cpu &pt_cpu, const std::vector<lldb::TargetSP> &targets)
-      : m_pt_cpu(pt_cpu) {
-    for (const lldb::TargetSP &target_sp : targets)
-      m_targets.push_back(target_sp);
-  }
+  friend class TraceIntelPTSessionFileParser;
+
+  /// \param[in] trace_threads
+  ///     ThreadTrace instances, which are not live-processes and whose trace
+  ///     files are fixed.
+  TraceIntelPT(const pt_cpu &pt_cpu,
+               const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads);
 
   pt_cpu m_pt_cpu;
-  std::vector<std::weak_ptr<Target>> m_targets;
+  std::map<std::pair<lldb::pid_t, lldb::tid_t>, std::shared_ptr<ThreadTrace>>
+      m_trace_threads;
 };
 
 } // namespace trace_intel_pt

diff  --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
index 4b439000a153..beef5c3968ea 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
@@ -8,10 +8,11 @@
 
 #include "TraceIntelPTSessionFileParser.h"
 
-#include "ThreadIntelPT.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadList.h"
+#include "lldb/Target/ThreadTrace.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -34,88 +35,39 @@ StringRef TraceIntelPTSessionFileParser::GetSchema() {
   return schema;
 }
 
-void TraceIntelPTSessionFileParser::ParseThread(
-    ProcessSP &process_sp, const TraceSessionFileParser::JSONThread &thread) {
-  lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid);
-
-  FileSpec trace_file(thread.trace_file);
-  NormalizePath(trace_file);
-
-  ThreadSP thread_sp =
-      std::make_shared<ThreadIntelPT>(*process_sp, tid, trace_file);
-  process_sp->GetThreadList().AddThread(thread_sp);
+pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(const JSONPTCPU &pt_cpu) {
+  return {pt_cpu.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
+          static_cast<uint16_t>(pt_cpu.family),
+          static_cast<uint8_t>(pt_cpu.model),
+          static_cast<uint8_t>(pt_cpu.stepping)};
 }
 
-Error TraceIntelPTSessionFileParser::ParseProcess(
-    const TraceSessionFileParser::JSONProcess &process) {
-  TargetSP target_sp;
-  Status error = m_debugger.GetTargetList().CreateTarget(
-      m_debugger, /*user_exe_path*/ StringRef(), process.triple,
-      eLoadDependentsNo,
-      /*platform_options*/ nullptr, target_sp);
-
-  if (!target_sp)
-    return error.ToError();
-
-  m_targets.push_back(target_sp);
-  m_debugger.GetTargetList().SetSelectedTarget(target_sp.get());
-
-  ProcessSP process_sp(target_sp->CreateProcess(
-      /*listener*/ nullptr, "trace",
-      /*crash_file*/ nullptr));
-  process_sp->SetID(static_cast<lldb::pid_t>(process.pid));
+TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
+    const pt_cpu &pt_cpu, std::vector<ParsedProcess> &parsed_processes) {
+  std::vector<ThreadTraceSP> threads;
+  for (const ParsedProcess &parsed_process : parsed_processes)
+    threads.insert(threads.end(), parsed_process.threads.begin(),
+                   parsed_process.threads.end());
 
-  for (const TraceSessionFileParser::JSONThread &thread : process.threads)
-    ParseThread(process_sp, thread);
+  TraceSP trace_instance(new TraceIntelPT(pt_cpu, threads));
+  for (const ParsedProcess &parsed_process : parsed_processes)
+    parsed_process.target_sp->SetTrace(trace_instance);
 
-  for (const TraceSessionFileParser::JSONModule &module : process.modules) {
-    if (Error err = ParseModule(target_sp, module))
-      return err;
-  }
-
-  if (!process.threads.empty())
-    process_sp->GetThreadList().SetSelectedThreadByIndexID(0);
-
-  // We invoke DidAttach to create a correct stopped state for the process and
-  // its threads.
-  ArchSpec process_arch;
-  process_sp->DidAttach(process_arch);
-
-  return llvm::Error::success();
+  return trace_instance;
 }
 
-void TraceIntelPTSessionFileParser::ParsePTCPU(const JSONPTCPU &pt_cpu) {
-  m_pt_cpu = {pt_cpu.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
-              static_cast<uint16_t>(pt_cpu.family),
-              static_cast<uint8_t>(pt_cpu.model),
-              static_cast<uint8_t>(pt_cpu.stepping)};
-}
-
-Error TraceIntelPTSessionFileParser::ParseImpl() {
+Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
   json::Path::Root root("traceSession");
   TraceSessionFileParser::JSONTraceSession<JSONTraceIntelPTSettings> session;
-  if (!json::fromJSON(m_trace_session_file, session, root)) {
+  if (!json::fromJSON(m_trace_session_file, session, root))
     return CreateJSONError(root, m_trace_session_file);
-  }
-
-  ParsePTCPU(session.trace.pt_cpu);
-  for (const TraceSessionFileParser::JSONProcess &process : session.processes) {
-    if (Error err = ParseProcess(process))
-      return err;
-  }
-  return Error::success();
-}
-
-Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
-  if (Error err = ParseImpl()) {
-    // Delete all targets that were created
-    for (auto target_sp : m_targets)
-      m_debugger.GetTargetList().DeleteTarget(target_sp);
-    m_targets.clear();
-    return std::move(err);
-  }
 
-  return TraceIntelPT::CreateInstance(m_pt_cpu, m_targets);
+  if (Expected<std::vector<ParsedProcess>> parsed_processes =
+          ParseCommonSessionFile(session))
+    return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.pt_cpu),
+                                      *parsed_processes);
+  else
+    return parsed_processes.takeError();
 }
 
 namespace llvm {

diff  --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
index 64f620042ef7..6a896de09d00 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
@@ -9,8 +9,6 @@
 #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
 
-#include "intel-pt.h"
-
 #include "TraceIntelPT.h"
 #include "lldb/Target/TraceSessionFileParser.h"
 
@@ -38,8 +36,8 @@ class TraceIntelPTSessionFileParser : public TraceSessionFileParser {
   TraceIntelPTSessionFileParser(Debugger &debugger,
                                 const llvm::json::Value &trace_session_file,
                                 llvm::StringRef session_file_dir)
-      : TraceSessionFileParser(session_file_dir, GetSchema()),
-        m_debugger(debugger), m_trace_session_file(trace_session_file) {}
+      : TraceSessionFileParser(debugger, session_file_dir, GetSchema()),
+        m_trace_session_file(trace_session_file) {}
 
   /// \return
   ///   The JSON schema for the session data.
@@ -53,24 +51,14 @@ class TraceIntelPTSessionFileParser : public TraceSessionFileParser {
   ///   errors, return a null pointer.
   llvm::Expected<lldb::TraceSP> Parse();
 
-private:
-  llvm::Error ParseImpl();
-
-  llvm::Error ParseProcess(const TraceSessionFileParser::JSONProcess &process);
+  lldb::TraceSP
+  CreateTraceIntelPTInstance(const pt_cpu &pt_cpu,
+                             std::vector<ParsedProcess> &parsed_processes);
 
-  void ParseThread(lldb::ProcessSP &process_sp,
-                   const TraceSessionFileParser::JSONThread &thread);
-
-  void ParsePTCPU(const JSONPTCPU &pt_cpu);
+private:
+  pt_cpu ParsePTCPU(const JSONPTCPU &pt_cpu);
 
-  Debugger &m_debugger;
   const llvm::json::Value &m_trace_session_file;
-
-  /// Objects created as product of the parsing
-  /// \{
-  pt_cpu m_pt_cpu;
-  std::vector<lldb::TargetSP> m_targets;
-  /// \}
 };
 
 } // namespace trace_intel_pt

diff  --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt
index 8374fcca8451..383ac5a6c53c 100644
--- a/lldb/source/Target/CMakeLists.txt
+++ b/lldb/source/Target/CMakeLists.txt
@@ -24,6 +24,7 @@ add_lldb_library(lldbTarget
   PathMappingList.cpp
   Platform.cpp
   Process.cpp
+  ProcessTrace.cpp
   Queue.cpp
   QueueItem.cpp
   QueueList.cpp
@@ -65,6 +66,7 @@ add_lldb_library(lldbTarget
   ThreadPlanTracer.cpp
   ThreadPlanStack.cpp
   ThreadSpec.cpp
+  ThreadTrace.cpp
   Trace.cpp
   TraceSessionFileParser.cpp
   UnixSignals.cpp

diff  --git a/lldb/source/Plugins/Process/Trace/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp
similarity index 97%
rename from lldb/source/Plugins/Process/Trace/ProcessTrace.cpp
rename to lldb/source/Target/ProcessTrace.cpp
index f727336e4d21..768df0bfe4dd 100644
--- a/lldb/source/Plugins/Process/Trace/ProcessTrace.cpp
+++ b/lldb/source/Target/ProcessTrace.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ProcessTrace.h"
+#include "lldb/Target/ProcessTrace.h"
 
 #include <memory>
 
@@ -16,9 +16,6 @@
 
 using namespace lldb;
 using namespace lldb_private;
-using namespace lldb_private::process_trace;
-
-LLDB_PLUGIN_DEFINE(ProcessTrace)
 
 ConstString ProcessTrace::GetPluginNameStatic() {
   static ConstString g_name("trace");

diff  --git a/lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.cpp b/lldb/source/Target/ThreadTrace.cpp
similarity index 68%
rename from lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.cpp
rename to lldb/source/Target/ThreadTrace.cpp
index 05650018bfd1..346f36a737d7 100644
--- a/lldb/source/Plugins/Trace/intel-pt/ThreadIntelPT.cpp
+++ b/lldb/source/Target/ThreadTrace.cpp
@@ -1,4 +1,4 @@
-//===-- ThreadIntelPT.cpp -------------------------------------------------===//
+//===-- ThreadTrace.cpp ---------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ThreadIntelPT.h"
+#include "lldb/Target/ThreadTrace.h"
 
 #include <memory>
 
@@ -16,11 +16,10 @@
 
 using namespace lldb;
 using namespace lldb_private;
-using namespace lldb_private::trace_intel_pt;
 
-void ThreadIntelPT::RefreshStateAfterStop() {}
+void ThreadTrace::RefreshStateAfterStop() {}
 
-RegisterContextSP ThreadIntelPT::GetRegisterContext() {
+RegisterContextSP ThreadTrace::GetRegisterContext() {
   if (!m_reg_context_sp)
     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
 
@@ -28,11 +27,13 @@ RegisterContextSP ThreadIntelPT::GetRegisterContext() {
 }
 
 RegisterContextSP
-ThreadIntelPT::CreateRegisterContextForFrame(StackFrame *frame) {
+ThreadTrace::CreateRegisterContextForFrame(StackFrame *frame) {
   // Eventually this will calculate the register context based on the current
   // trace position.
   return std::make_shared<RegisterContextHistory>(
       *this, 0, GetProcess()->GetAddressByteSize(), LLDB_INVALID_ADDRESS);
 }
 
-bool ThreadIntelPT::CalculateStopInfo() { return false; }
+bool ThreadTrace::CalculateStopInfo() { return false; }
+
+const FileSpec &ThreadTrace::GetTraceFile() const { return m_trace_file; }

diff  --git a/lldb/source/Target/TraceSessionFileParser.cpp b/lldb/source/Target/TraceSessionFileParser.cpp
index d164d1fc2418..41fc35c4ed9e 100644
--- a/lldb/source/Target/TraceSessionFileParser.cpp
+++ b/lldb/source/Target/TraceSessionFileParser.cpp
@@ -10,8 +10,11 @@
 
 #include <sstream>
 
+#include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadTrace.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -87,6 +90,81 @@ std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) {
   return schema_builder.str();
 }
 
+ThreadTraceSP TraceSessionFileParser::ParseThread(ProcessSP &process_sp,
+                                                  const JSONThread &thread) {
+  lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid);
+
+  FileSpec trace_file(thread.trace_file);
+  NormalizePath(trace_file);
+
+  ThreadTraceSP thread_sp =
+      std::make_shared<ThreadTrace>(*process_sp, tid, trace_file);
+  process_sp->GetThreadList().AddThread(thread_sp);
+  return thread_sp;
+}
+
+Expected<TraceSessionFileParser::ParsedProcess>
+TraceSessionFileParser::ParseProcess(const JSONProcess &process) {
+  TargetSP target_sp;
+  Status error = m_debugger.GetTargetList().CreateTarget(
+      m_debugger, /*user_exe_path*/ StringRef(), process.triple,
+      eLoadDependentsNo,
+      /*platform_options*/ nullptr, target_sp);
+
+  if (!target_sp)
+    return error.ToError();
+
+  ParsedProcess parsed_process;
+  parsed_process.target_sp = target_sp;
+
+  m_debugger.GetTargetList().SetSelectedTarget(target_sp.get());
+
+  ProcessSP process_sp = target_sp->CreateProcess(
+      /*listener*/ nullptr, "trace",
+      /*crash_file*/ nullptr);
+
+  process_sp->SetID(static_cast<lldb::pid_t>(process.pid));
+
+  for (const JSONThread &thread : process.threads)
+    parsed_process.threads.push_back(ParseThread(process_sp, thread));
+
+  for (const JSONModule &module : process.modules)
+    if (Error err = ParseModule(target_sp, module))
+      return std::move(err);
+
+  if (!process.threads.empty())
+    process_sp->GetThreadList().SetSelectedThreadByIndexID(0);
+
+  // We invoke DidAttach to create a correct stopped state for the process and
+  // its threads.
+  ArchSpec process_arch;
+  process_sp->DidAttach(process_arch);
+
+  return parsed_process;
+}
+
+Expected<std::vector<TraceSessionFileParser::ParsedProcess>>
+TraceSessionFileParser::ParseCommonSessionFile(
+    const JSONTraceSessionBase &session) {
+  std::vector<ParsedProcess> parsed_processes;
+
+  auto onError = [&]() {
+    // Delete all targets that were created so far in case of failures
+    for (ParsedProcess &parsed_process : parsed_processes)
+      m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp);
+  };
+
+  for (const JSONProcess &process : session.processes) {
+    if (Expected<ParsedProcess> parsed_process = ParseProcess(process))
+      parsed_processes.push_back(std::move(*parsed_process));
+    else {
+      onError();
+      return parsed_process.takeError();
+    }
+  }
+  return parsed_processes;
+}
+
 namespace llvm {
 namespace json {
 
@@ -129,5 +207,12 @@ bool fromJSON(const Value &value,
   return o && o.map("type", plugin_settings.type);
 }
 
+bool fromJSON(const Value &value,
+              TraceSessionFileParser::JSONTraceSessionBase &session,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("processes", session.processes);
+}
+
 } // namespace json
 } // namespace llvm


        


More information about the lldb-commits mailing list