[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