forked from OSchip/llvm-project
[NFC][lldb][trace] Rename trace session to trace bundle
As previously discussed with @jj10306, we didn't really have a name for the post-mortem (or offline) trace session representation, which is in fact a folder with a bunch of files. We decided to call this folder "trace bundle", and the main JSON file in it "trace bundle description file". This naming is pretty decent, so I'm refactoring all the existing code to account for that. Differential Revision: https://reviews.llvm.org/D128484
This commit is contained in:
parent
07b7fada73
commit
b8dcd0ba26
|
@ -336,21 +336,21 @@ public:
|
|||
// Trace
|
||||
static bool RegisterPlugin(
|
||||
llvm::StringRef name, llvm::StringRef description,
|
||||
TraceCreateInstanceForSessionFile create_callback_for_session_file,
|
||||
TraceCreateInstanceFromBundle create_callback_from_bundle,
|
||||
TraceCreateInstanceForLiveProcess create_callback_for_live_process,
|
||||
llvm::StringRef schema);
|
||||
|
||||
static bool
|
||||
UnregisterPlugin(TraceCreateInstanceForSessionFile create_callback);
|
||||
UnregisterPlugin(TraceCreateInstanceFromBundle create_callback);
|
||||
|
||||
static TraceCreateInstanceForSessionFile
|
||||
static TraceCreateInstanceFromBundle
|
||||
GetTraceCreateCallback(llvm::StringRef plugin_name);
|
||||
|
||||
static TraceCreateInstanceForLiveProcess
|
||||
GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name);
|
||||
|
||||
/// Get the JSON schema for a trace session file corresponding to the given
|
||||
/// plugin.
|
||||
/// Get the JSON schema for a trace bundle description file corresponding to
|
||||
/// the given plugin.
|
||||
///
|
||||
/// \param[in] plugin_name
|
||||
/// The name of the plugin.
|
||||
|
@ -360,8 +360,8 @@ public:
|
|||
/// otherwise the actual schema is returned.
|
||||
static llvm::StringRef GetTraceSchema(llvm::StringRef plugin_name);
|
||||
|
||||
/// Get the JSON schema for a trace session file corresponding to the plugin
|
||||
/// given by its index.
|
||||
/// Get the JSON schema for a trace bundle description file corresponding to
|
||||
/// the plugin given by its index.
|
||||
///
|
||||
/// \param[in] index
|
||||
/// The index of the plugin to get the schema of.
|
||||
|
|
|
@ -102,17 +102,14 @@ public:
|
|||
/// The debugger instance where new Targets will be created as part of the
|
||||
/// JSON data parsing.
|
||||
///
|
||||
/// \param[in] trace_session_file
|
||||
/// The contents of the trace session file describing the trace session.
|
||||
/// See \a TraceSessionFileParser::BuildSchema for more information about
|
||||
/// the schema of this JSON file.
|
||||
/// \param[in] bundle_description
|
||||
/// The trace bundle description object describing the trace session.
|
||||
///
|
||||
/// \param[in] session_file_dir
|
||||
/// The path to the directory that contains the session file. It's used to
|
||||
/// resolved relative paths in the session file.
|
||||
/// \param[in] bundle_dir
|
||||
/// The path to the directory that contains the trace bundle.
|
||||
static llvm::Expected<lldb::TraceSP>
|
||||
FindPluginForPostMortemProcess(Debugger &debugger,
|
||||
const llvm::json::Value &trace_session_file,
|
||||
const llvm::json::Value &bundle_description,
|
||||
llvm::StringRef session_file_dir);
|
||||
|
||||
/// Find a trace plug-in to trace a live process.
|
||||
|
|
|
@ -115,8 +115,8 @@ 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,
|
||||
typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceFromBundle)(
|
||||
const llvm::json::Value &trace_bundle_description,
|
||||
llvm::StringRef session_file_dir, lldb_private::Debugger &debugger);
|
||||
typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForLiveProcess)(
|
||||
Process &process);
|
||||
|
|
|
@ -72,9 +72,10 @@ public:
|
|||
};
|
||||
|
||||
CommandObjectTraceLoad(CommandInterpreter &interpreter)
|
||||
: CommandObjectParsed(interpreter, "trace load",
|
||||
"Load a processor trace session from a JSON file.",
|
||||
"trace load") {}
|
||||
: CommandObjectParsed(
|
||||
interpreter, "trace load",
|
||||
"Load a post-mortem processor trace session from a trace bundle.",
|
||||
"trace load") {}
|
||||
|
||||
~CommandObjectTraceLoad() override = default;
|
||||
|
||||
|
@ -83,9 +84,8 @@ public:
|
|||
protected:
|
||||
bool DoExecute(Args &command, CommandReturnObject &result) override {
|
||||
if (command.size() != 1) {
|
||||
result.AppendError(
|
||||
"a single path to a JSON file containing a trace session"
|
||||
" is required");
|
||||
result.AppendError("a single path to a JSON file containing a the "
|
||||
"description of the trace bundle is required");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1033,14 +1033,14 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
|
|||
#pragma mark Trace
|
||||
|
||||
struct TraceInstance
|
||||
: public PluginInstance<TraceCreateInstanceForSessionFile> {
|
||||
: public PluginInstance<TraceCreateInstanceFromBundle> {
|
||||
TraceInstance(
|
||||
llvm::StringRef name, llvm::StringRef description,
|
||||
CallbackType create_callback_for_session_file,
|
||||
CallbackType create_callback_from_bundle,
|
||||
TraceCreateInstanceForLiveProcess create_callback_for_live_process,
|
||||
llvm::StringRef schema)
|
||||
: PluginInstance<TraceCreateInstanceForSessionFile>(
|
||||
name, description, create_callback_for_session_file),
|
||||
: PluginInstance<TraceCreateInstanceFromBundle>(
|
||||
name, description, create_callback_from_bundle),
|
||||
schema(schema),
|
||||
create_callback_for_live_process(create_callback_for_live_process) {}
|
||||
|
||||
|
@ -1057,21 +1057,21 @@ static TraceInstances &GetTracePluginInstances() {
|
|||
|
||||
bool PluginManager::RegisterPlugin(
|
||||
llvm::StringRef name, llvm::StringRef description,
|
||||
TraceCreateInstanceForSessionFile create_callback_for_session_file,
|
||||
TraceCreateInstanceFromBundle create_callback_from_bundle,
|
||||
TraceCreateInstanceForLiveProcess create_callback_for_live_process,
|
||||
llvm::StringRef schema) {
|
||||
return GetTracePluginInstances().RegisterPlugin(
|
||||
name, description, create_callback_for_session_file,
|
||||
name, description, create_callback_from_bundle,
|
||||
create_callback_for_live_process, schema);
|
||||
}
|
||||
|
||||
bool PluginManager::UnregisterPlugin(
|
||||
TraceCreateInstanceForSessionFile create_callback_for_session_file) {
|
||||
TraceCreateInstanceFromBundle create_callback_from_bundle) {
|
||||
return GetTracePluginInstances().UnregisterPlugin(
|
||||
create_callback_for_session_file);
|
||||
create_callback_from_bundle);
|
||||
}
|
||||
|
||||
TraceCreateInstanceForSessionFile
|
||||
TraceCreateInstanceFromBundle
|
||||
PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
|
||||
return GetTracePluginInstances().GetCallbackForName(plugin_name);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace lldb_private {
|
|||
/// 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 ThreadPostMortemTrace : public Thread {
|
||||
public:
|
||||
/// \param[in] process
|
||||
|
|
|
@ -24,8 +24,8 @@ add_lldb_library(lldbPluginTraceIntelPT PLUGIN
|
|||
TraceIntelPT.cpp
|
||||
TraceIntelPTJSONStructs.cpp
|
||||
TraceIntelPTMultiCpuDecoder.cpp
|
||||
TraceIntelPTSessionFileParser.cpp
|
||||
TraceIntelPTSessionSaver.cpp
|
||||
TraceIntelPTBundleLoader.cpp
|
||||
TraceIntelPTBundleSaver.cpp
|
||||
|
||||
LINK_LIBS
|
||||
lldbCore
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
|
||||
|
||||
#include "ThreadDecoder.h"
|
||||
#include "TraceIntelPTSessionFileParser.h"
|
||||
|
||||
namespace lldb_private {
|
||||
namespace trace_intel_pt {
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#include "CommandObjectTraceStartIntelPT.h"
|
||||
#include "DecodedThread.h"
|
||||
#include "TraceIntelPTConstants.h"
|
||||
#include "TraceIntelPTSessionFileParser.h"
|
||||
#include "TraceIntelPTSessionSaver.h"
|
||||
#include "TraceIntelPTBundleLoader.h"
|
||||
#include "TraceIntelPTBundleSaver.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
@ -40,32 +40,32 @@ TraceIntelPT::GetThreadTraceStartCommand(CommandInterpreter &interpreter) {
|
|||
|
||||
void TraceIntelPT::Initialize() {
|
||||
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Intel Processor Trace",
|
||||
CreateInstanceForSessionFile,
|
||||
CreateInstanceForTraceBundle,
|
||||
CreateInstanceForLiveProcess,
|
||||
TraceIntelPTSessionFileParser::GetSchema());
|
||||
TraceIntelPTBundleLoader::GetSchema());
|
||||
}
|
||||
|
||||
void TraceIntelPT::Terminate() {
|
||||
PluginManager::UnregisterPlugin(CreateInstanceForSessionFile);
|
||||
PluginManager::UnregisterPlugin(CreateInstanceForTraceBundle);
|
||||
}
|
||||
|
||||
StringRef TraceIntelPT::GetSchema() {
|
||||
return TraceIntelPTSessionFileParser::GetSchema();
|
||||
return TraceIntelPTBundleLoader::GetSchema();
|
||||
}
|
||||
|
||||
void TraceIntelPT::Dump(Stream *s) const {}
|
||||
|
||||
llvm::Error TraceIntelPT::SaveLiveTraceToDisk(FileSpec directory) {
|
||||
RefreshLiveProcessState();
|
||||
return TraceIntelPTSessionSaver().SaveToDisk(*this, directory);
|
||||
return TraceIntelPTBundleSaver().SaveToDisk(*this, directory);
|
||||
}
|
||||
|
||||
Expected<TraceSP> TraceIntelPT::CreateInstanceForSessionFile(
|
||||
const json::Value &trace_session_file, StringRef session_file_dir,
|
||||
Expected<TraceSP> TraceIntelPT::CreateInstanceForTraceBundle(
|
||||
const json::Value &bundle_description, StringRef bundle_dir,
|
||||
Debugger &debugger) {
|
||||
return TraceIntelPTSessionFileParser(debugger, trace_session_file,
|
||||
session_file_dir)
|
||||
.Parse();
|
||||
return TraceIntelPTBundleLoader(debugger, bundle_description,
|
||||
bundle_dir)
|
||||
.Load();
|
||||
}
|
||||
|
||||
Expected<TraceSP> TraceIntelPT::CreateInstanceForLiveProcess(Process &process) {
|
||||
|
@ -79,15 +79,15 @@ TraceIntelPTSP TraceIntelPT::GetSharedPtr() {
|
|||
}
|
||||
|
||||
TraceIntelPTSP TraceIntelPT::CreateInstanceForPostmortemTrace(
|
||||
JSONTraceSession &session, ArrayRef<ProcessSP> traced_processes,
|
||||
JSONTraceBundleDescription &bundle_description, ArrayRef<ProcessSP> traced_processes,
|
||||
ArrayRef<ThreadPostMortemTraceSP> traced_threads) {
|
||||
TraceIntelPTSP trace_sp(new TraceIntelPT(session, traced_processes));
|
||||
trace_sp->m_storage.tsc_conversion = session.tsc_perf_zero_conversion;
|
||||
TraceIntelPTSP trace_sp(new TraceIntelPT(bundle_description, traced_processes));
|
||||
trace_sp->m_storage.tsc_conversion = bundle_description.tsc_perf_zero_conversion;
|
||||
|
||||
if (session.cpus) {
|
||||
if (bundle_description.cpus) {
|
||||
std::vector<cpu_id_t> cpus;
|
||||
|
||||
for (const JSONCpu &cpu : *session.cpus) {
|
||||
for (const JSONCpu &cpu : *bundle_description.cpus) {
|
||||
trace_sp->SetPostMortemCpuDataFile(cpu.id, IntelPTDataKinds::kIptTrace,
|
||||
FileSpec(cpu.ipt_trace));
|
||||
|
||||
|
@ -98,7 +98,7 @@ TraceIntelPTSP TraceIntelPT::CreateInstanceForPostmortemTrace(
|
|||
}
|
||||
|
||||
std::vector<tid_t> tids;
|
||||
for (const JSONProcess &process : session.processes)
|
||||
for (const JSONProcess &process : bundle_description.processes)
|
||||
for (const JSONThread &thread : process.threads)
|
||||
tids.push_back(thread.tid);
|
||||
|
||||
|
@ -119,10 +119,10 @@ TraceIntelPTSP TraceIntelPT::CreateInstanceForPostmortemTrace(
|
|||
return trace_sp;
|
||||
}
|
||||
|
||||
TraceIntelPT::TraceIntelPT(JSONTraceSession &session,
|
||||
TraceIntelPT::TraceIntelPT(JSONTraceBundleDescription &bundle_description,
|
||||
ArrayRef<ProcessSP> traced_processes)
|
||||
: Trace(traced_processes, session.GetCpuIds()),
|
||||
m_cpu_info(session.cpu_info) {}
|
||||
: Trace(traced_processes, bundle_description.GetCpuIds()),
|
||||
m_cpu_info(bundle_description.cpu_info) {}
|
||||
|
||||
DecodedThreadSP TraceIntelPT::Decode(Thread &thread) {
|
||||
if (const char *error = RefreshLiveProcessState())
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "TaskTimer.h"
|
||||
#include "ThreadDecoder.h"
|
||||
#include "TraceIntelPTMultiCpuDecoder.h"
|
||||
#include "TraceIntelPTSessionFileParser.h"
|
||||
#include "TraceIntelPTBundleLoader.h"
|
||||
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/lldb-types.h"
|
||||
|
@ -39,12 +39,11 @@ public:
|
|||
|
||||
/// Create an instance of this class from a trace bundle.
|
||||
///
|
||||
/// \param[in] trace_session_file
|
||||
/// The contents of the trace session file. See \a Trace::FindPlugin.
|
||||
/// \param[in] trace_bundle_description
|
||||
/// The description of the trace bundle. See \a Trace::FindPlugin.
|
||||
///
|
||||
/// \param[in] session_file_dir
|
||||
/// The path to the directory that contains the session file. It's used to
|
||||
/// resolved relative paths in the session file.
|
||||
/// \param[in] bundle_dir
|
||||
/// The path to the directory that contains the trace bundle.
|
||||
///
|
||||
/// \param[in] debugger
|
||||
/// The debugger instance where new Targets will be created as part of the
|
||||
|
@ -53,8 +52,8 @@ public:
|
|||
/// \return
|
||||
/// A trace instance or an error in case of failures.
|
||||
static llvm::Expected<lldb::TraceSP>
|
||||
CreateInstanceForSessionFile(const llvm::json::Value &trace_session_file,
|
||||
llvm::StringRef session_file_dir,
|
||||
CreateInstanceForTraceBundle(const llvm::json::Value &trace_bundle_description,
|
||||
llvm::StringRef bundle_dir,
|
||||
Debugger &debugger);
|
||||
|
||||
static llvm::Expected<lldb::TraceSP>
|
||||
|
@ -161,14 +160,14 @@ public:
|
|||
TraceIntelPTSP GetSharedPtr();
|
||||
|
||||
private:
|
||||
friend class TraceIntelPTSessionFileParser;
|
||||
friend class TraceIntelPTBundleLoader;
|
||||
|
||||
llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess();
|
||||
|
||||
/// Postmortem trace constructor
|
||||
///
|
||||
/// \param[in] session
|
||||
/// The definition file for the postmortem session.
|
||||
/// \param[in] bundle_description
|
||||
/// The definition file for the postmortem bundle.
|
||||
///
|
||||
/// \param[in] traced_processes
|
||||
/// The processes traced in the live session.
|
||||
|
@ -181,13 +180,13 @@ private:
|
|||
/// A TraceIntelPT shared pointer instance.
|
||||
/// \{
|
||||
static TraceIntelPTSP CreateInstanceForPostmortemTrace(
|
||||
JSONTraceSession &session,
|
||||
JSONTraceBundleDescription &bundle_description,
|
||||
llvm::ArrayRef<lldb::ProcessSP> traced_processes,
|
||||
llvm::ArrayRef<lldb::ThreadPostMortemTraceSP> traced_threads);
|
||||
|
||||
/// This constructor is used by CreateInstanceForPostmortemTrace to get the
|
||||
/// instance ready before using shared pointers, which is a limitation of C++.
|
||||
TraceIntelPT(JSONTraceSession &session,
|
||||
TraceIntelPT(JSONTraceBundleDescription &bundle_description,
|
||||
llvm::ArrayRef<lldb::ProcessSP> traced_processes);
|
||||
/// \}
|
||||
|
||||
|
@ -216,12 +215,12 @@ private:
|
|||
llvm::DenseMap<lldb::tid_t, std::unique_ptr<ThreadDecoder>> thread_decoders;
|
||||
/// Helper variable used to track long running operations for telemetry.
|
||||
TaskTimer task_timer;
|
||||
/// It is provided by either a session file or a live process to convert TSC
|
||||
/// It is provided by either a trace bundle or a live process to convert TSC
|
||||
/// counters to and from nanos. It might not be available on all hosts.
|
||||
llvm::Optional<LinuxPerfZeroTscConversion> tsc_conversion;
|
||||
} m_storage;
|
||||
|
||||
/// It is provided by either a session file or a live process' "cpuInfo"
|
||||
/// It is provided by either a trace bundle or a live process' "cpuInfo"
|
||||
/// binary data. We don't put it in the Storage because this variable doesn't
|
||||
/// change.
|
||||
llvm::Optional<pt_cpu> m_cpu_info;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- TraceIntelPTSessionFileParser.cpp ---------------------------------===//
|
||||
//===-- TraceIntelPTBundleLoader.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 "TraceIntelPTSessionFileParser.h"
|
||||
#include "TraceIntelPTBundleLoader.h"
|
||||
|
||||
#include "../common/ThreadPostMortemTrace.h"
|
||||
#include "TraceIntelPT.h"
|
||||
|
@ -22,14 +22,14 @@ using namespace lldb_private;
|
|||
using namespace lldb_private::trace_intel_pt;
|
||||
using namespace llvm;
|
||||
|
||||
FileSpec TraceIntelPTSessionFileParser::NormalizePath(const std::string &path) {
|
||||
FileSpec TraceIntelPTBundleLoader::NormalizePath(const std::string &path) {
|
||||
FileSpec file_spec(path);
|
||||
if (file_spec.IsRelative())
|
||||
file_spec.PrependPathComponent(m_session_file_dir);
|
||||
file_spec.PrependPathComponent(m_bundle_dir);
|
||||
return file_spec;
|
||||
}
|
||||
|
||||
Error TraceIntelPTSessionFileParser::ParseModule(Target &target,
|
||||
Error TraceIntelPTBundleLoader::ParseModule(Target &target,
|
||||
const JSONModule &module) {
|
||||
auto do_parse = [&]() -> Error {
|
||||
FileSpec system_file_spec(module.system_path);
|
||||
|
@ -63,7 +63,7 @@ Error TraceIntelPTSessionFileParser::ParseModule(Target &target,
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
Error TraceIntelPTSessionFileParser::CreateJSONError(json::Path::Root &root,
|
||||
Error TraceIntelPTBundleLoader::CreateJSONError(json::Path::Root &root,
|
||||
const json::Value &value) {
|
||||
std::string err;
|
||||
raw_string_ostream os(err);
|
||||
|
@ -74,7 +74,7 @@ Error TraceIntelPTSessionFileParser::CreateJSONError(json::Path::Root &root,
|
|||
}
|
||||
|
||||
ThreadPostMortemTraceSP
|
||||
TraceIntelPTSessionFileParser::ParseThread(Process &process,
|
||||
TraceIntelPTBundleLoader::ParseThread(Process &process,
|
||||
const JSONThread &thread) {
|
||||
lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid);
|
||||
|
||||
|
@ -88,8 +88,8 @@ TraceIntelPTSessionFileParser::ParseThread(Process &process,
|
|||
return thread_sp;
|
||||
}
|
||||
|
||||
Expected<TraceIntelPTSessionFileParser::ParsedProcess>
|
||||
TraceIntelPTSessionFileParser::ParseProcess(const JSONProcess &process) {
|
||||
Expected<TraceIntelPTBundleLoader::ParsedProcess>
|
||||
TraceIntelPTBundleLoader::ParseProcess(const JSONProcess &process) {
|
||||
TargetSP target_sp;
|
||||
Status error = m_debugger.GetTargetList().CreateTarget(
|
||||
m_debugger, /*user_exe_path*/ StringRef(), process.triple.getValueOr(""),
|
||||
|
@ -127,9 +127,9 @@ TraceIntelPTSessionFileParser::ParseProcess(const JSONProcess &process) {
|
|||
return parsed_process;
|
||||
}
|
||||
|
||||
Expected<std::vector<TraceIntelPTSessionFileParser::ParsedProcess>>
|
||||
TraceIntelPTSessionFileParser::ParseSessionFile(
|
||||
const JSONTraceSession &session) {
|
||||
Expected<std::vector<TraceIntelPTBundleLoader::ParsedProcess>>
|
||||
TraceIntelPTBundleLoader::LoadBundle(
|
||||
const JSONTraceBundleDescription &bundle_description) {
|
||||
std::vector<ParsedProcess> parsed_processes;
|
||||
|
||||
auto HandleError = [&](Error &&err) {
|
||||
|
@ -139,7 +139,7 @@ TraceIntelPTSessionFileParser::ParseSessionFile(
|
|||
return std::move(err);
|
||||
};
|
||||
|
||||
for (const JSONProcess &process : session.processes) {
|
||||
for (const JSONProcess &process : bundle_description.processes) {
|
||||
if (Expected<ParsedProcess> parsed_process = ParseProcess(process))
|
||||
parsed_processes.push_back(std::move(*parsed_process));
|
||||
else
|
||||
|
@ -149,7 +149,7 @@ TraceIntelPTSessionFileParser::ParseSessionFile(
|
|||
return parsed_processes;
|
||||
}
|
||||
|
||||
StringRef TraceIntelPTSessionFileParser::GetSchema() {
|
||||
StringRef TraceIntelPTBundleLoader::GetSchema() {
|
||||
static std::string schema;
|
||||
if (schema.empty()) {
|
||||
schema = R"({
|
||||
|
@ -218,7 +218,7 @@ StringRef TraceIntelPTSessionFileParser::GetSchema() {
|
|||
|
||||
Notes:
|
||||
|
||||
- All paths are either absolute or relative to folder containing the session file.
|
||||
- All paths are either absolute or relative to folder containing the bundle description file.
|
||||
- "cpus" is provided if and only if processes[].threads[].iptTrace is not provided.
|
||||
- "tscPerfZeroConversion" must be provided if "cpus" is provided.
|
||||
})";
|
||||
|
@ -226,12 +226,12 @@ Notes:
|
|||
return schema;
|
||||
}
|
||||
|
||||
Error TraceIntelPTSessionFileParser::AugmentThreadsFromContextSwitches(
|
||||
JSONTraceSession &session) {
|
||||
if (!session.cpus)
|
||||
Error TraceIntelPTBundleLoader::AugmentThreadsFromContextSwitches(
|
||||
JSONTraceBundleDescription &bundle_description) {
|
||||
if (!bundle_description.cpus)
|
||||
return Error::success();
|
||||
|
||||
if (!session.tsc_perf_zero_conversion)
|
||||
if (!bundle_description.tsc_perf_zero_conversion)
|
||||
return createStringError(inconvertibleErrorCode(),
|
||||
"TSC to nanos conversion values are needed when "
|
||||
"context switch information is provided.");
|
||||
|
@ -239,7 +239,7 @@ Error TraceIntelPTSessionFileParser::AugmentThreadsFromContextSwitches(
|
|||
DenseMap<lldb::pid_t, JSONProcess *> indexed_processes;
|
||||
DenseMap<JSONProcess *, DenseSet<tid_t>> indexed_threads;
|
||||
|
||||
for (JSONProcess &process : session.processes) {
|
||||
for (JSONProcess &process : bundle_description.processes) {
|
||||
indexed_processes[process.pid] = &process;
|
||||
for (JSONThread &thread : process.threads)
|
||||
indexed_threads[&process].insert(thread.tid);
|
||||
|
@ -255,13 +255,13 @@ Error TraceIntelPTSessionFileParser::AugmentThreadsFromContextSwitches(
|
|||
proc->second->threads.push_back({tid, /*ipt_trace=*/None});
|
||||
};
|
||||
|
||||
for (const JSONCpu &cpu : *session.cpus) {
|
||||
for (const JSONCpu &cpu : *bundle_description.cpus) {
|
||||
Error err = Trace::OnDataFileRead(
|
||||
FileSpec(cpu.context_switch_trace),
|
||||
[&](ArrayRef<uint8_t> data) -> Error {
|
||||
Expected<std::vector<ThreadContinuousExecution>> executions =
|
||||
DecodePerfContextSwitchTrace(data, cpu.id,
|
||||
*session.tsc_perf_zero_conversion);
|
||||
*bundle_description.tsc_perf_zero_conversion);
|
||||
if (!executions)
|
||||
return executions.takeError();
|
||||
for (const ThreadContinuousExecution &execution : *executions)
|
||||
|
@ -274,8 +274,8 @@ Error TraceIntelPTSessionFileParser::AugmentThreadsFromContextSwitches(
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
Expected<TraceSP> TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
|
||||
JSONTraceSession &session, std::vector<ParsedProcess> &parsed_processes) {
|
||||
Expected<TraceSP> TraceIntelPTBundleLoader::CreateTraceIntelPTInstance(
|
||||
JSONTraceBundleDescription &bundle_description, std::vector<ParsedProcess> &parsed_processes) {
|
||||
std::vector<ThreadPostMortemTraceSP> threads;
|
||||
std::vector<ProcessSP> processes;
|
||||
for (const ParsedProcess &parsed_process : parsed_processes) {
|
||||
|
@ -285,16 +285,16 @@ Expected<TraceSP> TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
|
|||
}
|
||||
|
||||
TraceSP trace_instance = TraceIntelPT::CreateInstanceForPostmortemTrace(
|
||||
session, processes, threads);
|
||||
bundle_description, processes, threads);
|
||||
for (const ParsedProcess &parsed_process : parsed_processes)
|
||||
parsed_process.target_sp->SetTrace(trace_instance);
|
||||
|
||||
return trace_instance;
|
||||
}
|
||||
|
||||
void TraceIntelPTSessionFileParser::NormalizeAllPaths(
|
||||
JSONTraceSession &session) {
|
||||
for (JSONProcess &process : session.processes) {
|
||||
void TraceIntelPTBundleLoader::NormalizeAllPaths(
|
||||
JSONTraceBundleDescription &bundle_description) {
|
||||
for (JSONProcess &process : bundle_description.processes) {
|
||||
for (JSONModule &module : process.modules) {
|
||||
module.system_path = NormalizePath(module.system_path).GetPath();
|
||||
if (module.file)
|
||||
|
@ -305,8 +305,8 @@ void TraceIntelPTSessionFileParser::NormalizeAllPaths(
|
|||
thread.ipt_trace = NormalizePath(*thread.ipt_trace).GetPath();
|
||||
}
|
||||
}
|
||||
if (session.cpus) {
|
||||
for (JSONCpu &cpu : *session.cpus) {
|
||||
if (bundle_description.cpus) {
|
||||
for (JSONCpu &cpu : *bundle_description.cpus) {
|
||||
cpu.context_switch_trace =
|
||||
NormalizePath(cpu.context_switch_trace).GetPath();
|
||||
cpu.ipt_trace = NormalizePath(cpu.ipt_trace).GetPath();
|
||||
|
@ -314,20 +314,20 @@ void TraceIntelPTSessionFileParser::NormalizeAllPaths(
|
|||
}
|
||||
}
|
||||
|
||||
Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
|
||||
json::Path::Root root("traceSession");
|
||||
JSONTraceSession session;
|
||||
if (!fromJSON(m_trace_session_file, session, root))
|
||||
return CreateJSONError(root, m_trace_session_file);
|
||||
Expected<TraceSP> TraceIntelPTBundleLoader::Load() {
|
||||
json::Path::Root root("traceBundle");
|
||||
JSONTraceBundleDescription bundle_description;
|
||||
if (!fromJSON(m_bundle_description, bundle_description, root))
|
||||
return CreateJSONError(root, m_bundle_description);
|
||||
|
||||
NormalizeAllPaths(session);
|
||||
NormalizeAllPaths(bundle_description);
|
||||
|
||||
if (Error err = AugmentThreadsFromContextSwitches(session))
|
||||
if (Error err = AugmentThreadsFromContextSwitches(bundle_description))
|
||||
return std::move(err);
|
||||
|
||||
if (Expected<std::vector<ParsedProcess>> parsed_processes =
|
||||
ParseSessionFile(session))
|
||||
return CreateTraceIntelPTInstance(session, *parsed_processes);
|
||||
LoadBundle(bundle_description))
|
||||
return CreateTraceIntelPTInstance(bundle_description, *parsed_processes);
|
||||
else
|
||||
return parsed_processes.takeError();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//===-- TraceIntelPTSessionFileParser.h -----------------------*- C++ //-*-===//
|
||||
//===-- TraceIntelPTBundleLoader.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.
|
||||
|
@ -6,8 +6,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
|
||||
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
|
||||
#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H
|
||||
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H
|
||||
|
||||
#include "../common/ThreadPostMortemTrace.h"
|
||||
#include "TraceIntelPTJSONStructs.h"
|
||||
|
@ -17,7 +17,7 @@ namespace trace_intel_pt {
|
|||
|
||||
class TraceIntelPT;
|
||||
|
||||
class TraceIntelPTSessionFileParser {
|
||||
class TraceIntelPTBundleLoader {
|
||||
public:
|
||||
/// Helper struct holding the objects created when parsing a process
|
||||
struct ParsedProcess {
|
||||
|
@ -28,32 +28,31 @@ public:
|
|||
/// \param[in] debugger
|
||||
/// The debugger that will own the targets to create.
|
||||
///
|
||||
/// \param[in] trace_session_file
|
||||
/// The contents of the main trace session definition file that follows the
|
||||
/// schema of the intel pt trace plug-in.
|
||||
/// \param[in] bundle_description
|
||||
/// The JSON description of a trace bundle that follows the schema of the intel pt trace plug-in.
|
||||
///
|
||||
/// \param[in] session_file_dir
|
||||
/// The folder where the trace session file is located.
|
||||
TraceIntelPTSessionFileParser(Debugger &debugger,
|
||||
const llvm::json::Value &trace_session_file,
|
||||
llvm::StringRef session_file_dir)
|
||||
: m_debugger(debugger), m_trace_session_file(trace_session_file),
|
||||
m_session_file_dir(session_file_dir) {}
|
||||
/// \param[in] bundle_dir
|
||||
/// The folder where the trace bundle is located.
|
||||
TraceIntelPTBundleLoader(Debugger &debugger,
|
||||
const llvm::json::Value &bundle_description,
|
||||
llvm::StringRef bundle_dir)
|
||||
: m_debugger(debugger), m_bundle_description(bundle_description),
|
||||
m_bundle_dir(bundle_dir) {}
|
||||
|
||||
/// \return
|
||||
/// The JSON schema for the session data.
|
||||
/// The JSON schema for the bundle description.
|
||||
static llvm::StringRef GetSchema();
|
||||
|
||||
/// Parse the structured data trace session and create the corresponding \a
|
||||
/// Parse the trace bundle description and create the corresponding \a
|
||||
/// Target objects. In case of an error, no targets are created.
|
||||
///
|
||||
/// \return
|
||||
/// A \a lldb::TraceSP instance with the trace session data. In case of
|
||||
/// A \a lldb::TraceSP instance created according to the trace bundle information. In case of
|
||||
/// errors, return a null pointer.
|
||||
llvm::Expected<lldb::TraceSP> Parse();
|
||||
llvm::Expected<lldb::TraceSP> Load();
|
||||
|
||||
private:
|
||||
/// Resolve non-absolute paths relative to the session file folder.
|
||||
/// Resolve non-absolute paths relative to the bundle folder.
|
||||
FileSpec NormalizePath(const std::string &path);
|
||||
|
||||
/// Create a post-mortem thread associated with the given \p process
|
||||
|
@ -61,10 +60,10 @@ private:
|
|||
lldb::ThreadPostMortemTraceSP ParseThread(Process &process,
|
||||
const JSONThread &thread);
|
||||
|
||||
/// Given a session description and a list of fully parsed processes,
|
||||
/// Given a bundle description and a list of fully parsed processes,
|
||||
/// create an actual Trace instance that "traces" these processes.
|
||||
llvm::Expected<lldb::TraceSP>
|
||||
CreateTraceIntelPTInstance(JSONTraceSession &session,
|
||||
CreateTraceIntelPTInstance(JSONTraceBundleDescription &bundle_description,
|
||||
std::vector<ParsedProcess> &parsed_processes);
|
||||
|
||||
/// Create the corresponding Threads and Process objects given the JSON
|
||||
|
@ -74,8 +73,7 @@ private:
|
|||
/// The JSON process definition
|
||||
llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
|
||||
|
||||
/// Create a moddule associated with the given \p target
|
||||
/// using the definition from \p module.
|
||||
/// Create a module associated with the given \p target using the definition from \p module.
|
||||
llvm::Error ParseModule(Target &target, const JSONModule &module);
|
||||
|
||||
/// Create a user-friendly error message upon a JSON-parsing failure using the
|
||||
|
@ -93,30 +91,30 @@ private:
|
|||
const llvm::json::Value &value);
|
||||
|
||||
/// Create the corresponding Process, Thread and Module objects given this
|
||||
/// session file.
|
||||
/// bundle description.
|
||||
llvm::Expected<std::vector<ParsedProcess>>
|
||||
ParseSessionFile(const JSONTraceSession &session);
|
||||
LoadBundle(const JSONTraceBundleDescription &bundle_description);
|
||||
|
||||
/// When applicable, augment the list of threads in the session file by
|
||||
/// When applicable, augment the list of threads in the trace bundle by
|
||||
/// inspecting the context switch trace. This only applies for threads of
|
||||
/// processes already specified in this session file.
|
||||
/// processes already specified in this bundle description.
|
||||
///
|
||||
/// \return
|
||||
/// An \a llvm::Error in case if failures, or \a llvm::Error::success
|
||||
/// otherwise.
|
||||
llvm::Error AugmentThreadsFromContextSwitches(JSONTraceSession &session);
|
||||
llvm::Error AugmentThreadsFromContextSwitches(JSONTraceBundleDescription &bundle_description);
|
||||
|
||||
/// Modifiy the session file by normalizing all the paths relative to the
|
||||
/// Modifiy the bundle description by normalizing all the paths relative to the
|
||||
/// session file directory.
|
||||
void NormalizeAllPaths(JSONTraceSession &session);
|
||||
void NormalizeAllPaths(JSONTraceBundleDescription &bundle_description);
|
||||
|
||||
Debugger &m_debugger;
|
||||
const llvm::json::Value &m_trace_session_file;
|
||||
const std::string m_session_file_dir;
|
||||
const llvm::json::Value &m_bundle_description;
|
||||
const std::string m_bundle_dir;
|
||||
};
|
||||
|
||||
} // namespace trace_intel_pt
|
||||
} // namespace lldb_private
|
||||
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
|
||||
#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H
|
|
@ -1,4 +1,4 @@
|
|||
//===-- TraceIntelPTSessionSaver.cpp --------------------------------------===//
|
||||
//===-- TraceIntelPTBundleSaver.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 "TraceIntelPTSessionSaver.h"
|
||||
#include "TraceIntelPTBundleSaver.h"
|
||||
#include "TraceIntelPT.h"
|
||||
#include "TraceIntelPTJSONStructs.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
|
@ -47,11 +47,11 @@ static llvm::Error WriteBytesToDisk(FileSpec &output_file,
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
/// Save the trace session description JSON object inside the given directory
|
||||
/// Save the trace bundle description JSON object inside the given directory
|
||||
/// as a file named \a trace.json.
|
||||
///
|
||||
/// \param[in] trace_session_json
|
||||
/// The trace's session, as JSON Object.
|
||||
/// \param[in] trace_bundle_description
|
||||
/// The trace bundle description as JSON Object.
|
||||
///
|
||||
/// \param[in] directory
|
||||
/// The directory where the JSON file will be saved.
|
||||
|
@ -60,12 +60,12 @@ static llvm::Error WriteBytesToDisk(FileSpec &output_file,
|
|||
/// \a llvm::Success if the operation was successful, or an \a llvm::Error
|
||||
/// otherwise.
|
||||
static llvm::Error
|
||||
WriteSessionToFile(const llvm::json::Value &trace_session_json,
|
||||
SaveTraceBundleDescription(const llvm::json::Value &trace_bundle_description,
|
||||
const FileSpec &directory) {
|
||||
FileSpec trace_path = directory;
|
||||
trace_path.AppendPathComponent("trace.json");
|
||||
std::ofstream os(trace_path.GetPath());
|
||||
os << formatv("{0:2}", trace_session_json).str();
|
||||
os << formatv("{0:2}", trace_bundle_description).str();
|
||||
os.close();
|
||||
if (!os)
|
||||
return createStringError(inconvertibleErrorCode(),
|
||||
|
@ -74,7 +74,7 @@ WriteSessionToFile(const llvm::json::Value &trace_session_json,
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
/// Build the threads sub-section of the trace session description file.
|
||||
/// Build the threads sub-section of the trace bundle description file.
|
||||
/// Any associated binary files are created inside the given directory.
|
||||
///
|
||||
/// \param[in] process
|
||||
|
@ -170,10 +170,10 @@ BuildCpusSection(TraceIntelPT &trace_ipt, FileSpec directory) {
|
|||
return json_cpus;
|
||||
}
|
||||
|
||||
/// Build modules sub-section of the trace's session. The original modules
|
||||
/// Build modules sub-section of the trace bundle. The original modules
|
||||
/// will be copied over to the \a <directory/modules> folder. Invalid modules
|
||||
/// are skipped.
|
||||
/// Copying the modules has the benefit of making these trace session
|
||||
/// Copying the modules has the benefit of making these
|
||||
/// directories self-contained, as the raw traces and modules are part of the
|
||||
/// output directory and can be sent to another machine, where lldb can load
|
||||
/// them and replicate exactly the same trace session.
|
||||
|
@ -235,7 +235,7 @@ BuildModulesSection(Process &process, FileSpec directory) {
|
|||
return json_modules;
|
||||
}
|
||||
|
||||
/// Build the processes section of the trace session description file. Besides
|
||||
/// Build the processes section of the trace bundle description object. Besides
|
||||
/// returning the processes information, this method saves to disk all modules
|
||||
/// and raw traces corresponding to the traced threads of the given process.
|
||||
///
|
||||
|
@ -280,7 +280,7 @@ BuildProcessesSection(TraceIntelPT &trace_ipt, const FileSpec &directory) {
|
|||
return processes;
|
||||
}
|
||||
|
||||
Error TraceIntelPTSessionSaver::SaveToDisk(TraceIntelPT &trace_ipt,
|
||||
Error TraceIntelPTBundleSaver::SaveToDisk(TraceIntelPT &trace_ipt,
|
||||
FileSpec directory) {
|
||||
if (std::error_code ec =
|
||||
sys::fs::create_directories(directory.GetPath().c_str()))
|
||||
|
@ -303,9 +303,9 @@ Error TraceIntelPTSessionSaver::SaveToDisk(TraceIntelPT &trace_ipt,
|
|||
if (!json_cpus)
|
||||
return json_cpus.takeError();
|
||||
|
||||
JSONTraceSession json_intel_pt_session{"intel-pt", *cpu_info, *json_processes,
|
||||
JSONTraceBundleDescription json_intel_pt_bundle_desc{"intel-pt", *cpu_info, *json_processes,
|
||||
*json_cpus,
|
||||
trace_ipt.GetPerfZeroTscConversion()};
|
||||
|
||||
return WriteSessionToFile(toJSON(json_intel_pt_session), directory);
|
||||
return SaveTraceBundleDescription(toJSON(json_intel_pt_bundle_desc), directory);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//===-- TraceIntelPTSessionSaver.h ---------------------------*- C++ //-*-===//
|
||||
//===-- TraceIntelPTBundleSaver.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.
|
||||
|
@ -6,8 +6,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H
|
||||
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H
|
||||
#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLESAVER_H
|
||||
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLESAVER_H
|
||||
|
||||
#include "TraceIntelPT.h"
|
||||
|
||||
|
@ -16,12 +16,12 @@
|
|||
namespace lldb_private {
|
||||
namespace trace_intel_pt {
|
||||
|
||||
class TraceIntelPTSessionSaver {
|
||||
class TraceIntelPTBundleSaver {
|
||||
public:
|
||||
/// Save the Intel PT trace of a live process to the specified directory,
|
||||
/// which will be created if needed. This will also create a file
|
||||
/// \a <directory>/trace.json with the main properties of the trace
|
||||
/// session, along with others files which contain the actual trace data.
|
||||
/// \a <directory>/trace.json with the description of the trace
|
||||
/// bundle, along with others files which contain the actual trace data.
|
||||
/// The trace.json file can be used later as input for the "trace load"
|
||||
/// command to load the trace in LLDB.
|
||||
///
|
||||
|
@ -29,7 +29,7 @@ public:
|
|||
/// The Intel PT trace to be saved to disk.
|
||||
///
|
||||
/// \param[in] directory
|
||||
/// The directory where the trace files will be saved.
|
||||
/// The directory where the trace bundle will be created.
|
||||
///
|
||||
/// \return
|
||||
/// \a llvm::success if the operation was successful, or an \a llvm::Error
|
||||
|
@ -40,4 +40,4 @@ public:
|
|||
} // namespace trace_intel_pt
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H
|
||||
#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLESAVER_H
|
|
@ -20,7 +20,7 @@ using namespace llvm::json;
|
|||
namespace lldb_private {
|
||||
namespace trace_intel_pt {
|
||||
|
||||
Optional<std::vector<lldb::cpu_id_t>> JSONTraceSession::GetCpuIds() {
|
||||
Optional<std::vector<lldb::cpu_id_t>> JSONTraceBundleDescription::GetCpuIds() {
|
||||
if (!cpus)
|
||||
return None;
|
||||
std::vector<lldb::cpu_id_t> cpu_ids;
|
||||
|
@ -116,30 +116,30 @@ bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) {
|
|||
return true;
|
||||
}
|
||||
|
||||
json::Value toJSON(const JSONTraceSession &session) {
|
||||
return Object{{"type", session.type},
|
||||
{"processes", session.processes},
|
||||
json::Value toJSON(const JSONTraceBundleDescription &bundle_description) {
|
||||
return Object{{"type", bundle_description.type},
|
||||
{"processes", bundle_description.processes},
|
||||
// We have to do this because the compiler fails at doing it
|
||||
// automatically because pt_cpu is not in a namespace
|
||||
{"cpuInfo", toJSON(session.cpu_info)},
|
||||
{"cpus", session.cpus},
|
||||
{"tscPerfZeroConversion", session.tsc_perf_zero_conversion}};
|
||||
{"cpuInfo", toJSON(bundle_description.cpu_info)},
|
||||
{"cpus", bundle_description.cpus},
|
||||
{"tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion}};
|
||||
}
|
||||
|
||||
bool fromJSON(const json::Value &value, JSONTraceSession &session, Path path) {
|
||||
bool fromJSON(const json::Value &value, JSONTraceBundleDescription &bundle_description, Path path) {
|
||||
ObjectMapper o(value, path);
|
||||
if (!(o && o.map("processes", session.processes) &&
|
||||
o.map("type", session.type) && o.map("cpus", session.cpus) &&
|
||||
o.map("tscPerfZeroConversion", session.tsc_perf_zero_conversion)))
|
||||
if (!(o && o.map("processes", bundle_description.processes) &&
|
||||
o.map("type", bundle_description.type) && o.map("cpus", bundle_description.cpus) &&
|
||||
o.map("tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion)))
|
||||
return false;
|
||||
if (session.cpus && !session.tsc_perf_zero_conversion) {
|
||||
if (bundle_description.cpus && !bundle_description.tsc_perf_zero_conversion) {
|
||||
path.report(
|
||||
"\"tscPerfZeroConversion\" is required when \"cpus\" is provided");
|
||||
return false;
|
||||
}
|
||||
// We have to do this because the compiler fails at doing it automatically
|
||||
// because pt_cpu is not in a namespace
|
||||
if (!fromJSON(*value.getAsObject()->get("cpuInfo"), session.cpu_info,
|
||||
if (!fromJSON(*value.getAsObject()->get("cpuInfo"), bundle_description.cpu_info,
|
||||
path.field("cpuInfo")))
|
||||
return false;
|
||||
return true;
|
||||
|
|
|
@ -47,7 +47,7 @@ struct JSONCpu {
|
|||
std::string context_switch_trace;
|
||||
};
|
||||
|
||||
struct JSONTraceSession {
|
||||
struct JSONTraceBundleDescription {
|
||||
std::string type;
|
||||
pt_cpu cpu_info;
|
||||
std::vector<JSONProcess> processes;
|
||||
|
@ -67,7 +67,7 @@ llvm::json::Value toJSON(const JSONCpu &cpu);
|
|||
|
||||
llvm::json::Value toJSON(const pt_cpu &cpu_info);
|
||||
|
||||
llvm::json::Value toJSON(const JSONTraceSession &session);
|
||||
llvm::json::Value toJSON(const JSONTraceBundleDescription &bundle_description);
|
||||
|
||||
bool fromJSON(const llvm::json::Value &value, JSONModule &module,
|
||||
llvm::json::Path path);
|
||||
|
@ -84,7 +84,7 @@ bool fromJSON(const llvm::json::Value &value, JSONCpu &cpu,
|
|||
bool fromJSON(const llvm::json::Value &value, pt_cpu &cpu_info,
|
||||
llvm::json::Path path);
|
||||
|
||||
bool fromJSON(const llvm::json::Value &value, JSONTraceSession &session,
|
||||
bool fromJSON(const llvm::json::Value &value, JSONTraceBundleDescription &bundle_description,
|
||||
llvm::json::Path path);
|
||||
} // namespace trace_intel_pt
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -24,19 +24,20 @@ using namespace lldb;
|
|||
using namespace lldb_private;
|
||||
using namespace llvm;
|
||||
|
||||
// Helper structs used to extract the type of a trace session json without
|
||||
// having to parse the entire object.
|
||||
// Helper structs used to extract the type of a JSON trace bundle description
|
||||
// object without having to parse the entire object.
|
||||
|
||||
struct JSONSimpleTraceSession {
|
||||
struct JSONSimpleTraceBundleDescription {
|
||||
std::string type;
|
||||
};
|
||||
|
||||
namespace llvm {
|
||||
namespace json {
|
||||
|
||||
bool fromJSON(const Value &value, JSONSimpleTraceSession &session, Path path) {
|
||||
bool fromJSON(const Value &value, JSONSimpleTraceBundleDescription &bundle,
|
||||
Path path) {
|
||||
json::ObjectMapper o(value, path);
|
||||
return o && o.map("type", session.type);
|
||||
return o && o.map("type", bundle.type);
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
@ -113,20 +114,19 @@ Trace::LoadPostMortemTraceFromFile(Debugger &debugger,
|
|||
trace_description_file.GetDirectory().AsCString());
|
||||
}
|
||||
|
||||
Expected<lldb::TraceSP>
|
||||
Trace::FindPluginForPostMortemProcess(Debugger &debugger,
|
||||
const json::Value &trace_session_file,
|
||||
StringRef session_file_dir) {
|
||||
JSONSimpleTraceSession json_session;
|
||||
json::Path::Root root("traceSession");
|
||||
if (!json::fromJSON(trace_session_file, json_session, root))
|
||||
Expected<lldb::TraceSP> Trace::FindPluginForPostMortemProcess(
|
||||
Debugger &debugger, const json::Value &trace_bundle_description,
|
||||
StringRef bundle_dir) {
|
||||
JSONSimpleTraceBundleDescription json_bundle;
|
||||
json::Path::Root root("traceBundle");
|
||||
if (!json::fromJSON(trace_bundle_description, json_bundle, root))
|
||||
return root.getError();
|
||||
|
||||
if (auto create_callback =
|
||||
PluginManager::GetTraceCreateCallback(json_session.type))
|
||||
return create_callback(trace_session_file, session_file_dir, debugger);
|
||||
PluginManager::GetTraceCreateCallback(json_bundle.type))
|
||||
return create_callback(trace_bundle_description, bundle_dir, debugger);
|
||||
|
||||
return createInvalidPlugInError(json_session.type);
|
||||
return createInvalidPlugInError(json_bundle.type);
|
||||
}
|
||||
|
||||
Expected<lldb::TraceSP> Trace::FindPluginForLiveProcess(llvm::StringRef name,
|
||||
|
|
|
@ -98,7 +98,7 @@ thread #1: tid = 3842849
|
|||
|
||||
# We test first an invalid type
|
||||
trace_description_file_path = os.path.join(src_dir, "intelpt-trace", "trace_bad.json")
|
||||
expected_substrs = ['''error: expected object at traceSession.processes[0]
|
||||
expected_substrs = ['''error: expected object at traceBundle.processes[0]
|
||||
|
||||
Context:
|
||||
{
|
||||
|
@ -124,15 +124,15 @@ Schema:
|
|||
self.traceLoad(traceDescriptionFilePath=trace_description_file_path, error=True, substrs=expected_substrs)
|
||||
|
||||
|
||||
# Now we test a wrong cpu family field in the global session file
|
||||
# Now we test a wrong cpu family field in the global bundle description file
|
||||
trace_description_file_path = os.path.join(src_dir, "intelpt-trace", "trace_bad2.json")
|
||||
expected_substrs = ['error: expected uint64_t at traceSession.cpuInfo.family', "Context", "Schema"]
|
||||
expected_substrs = ['error: expected uint64_t at traceBundle.cpuInfo.family', "Context", "Schema"]
|
||||
self.traceLoad(traceDescriptionFilePath=trace_description_file_path, error=True, substrs=expected_substrs)
|
||||
|
||||
|
||||
# Now we test a missing field in the intel-pt settings
|
||||
trace_description_file_path = os.path.join(src_dir, "intelpt-trace", "trace_bad4.json")
|
||||
expected_substrs = ['''error: missing value at traceSession.cpuInfo.family
|
||||
expected_substrs = ['''error: missing value at traceBundle.cpuInfo.family
|
||||
|
||||
Context:
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ Context:
|
|||
|
||||
# Now we test an incorrect load address in the intel-pt settings
|
||||
trace_description_file_path = os.path.join(src_dir, "intelpt-trace", "trace_bad5.json")
|
||||
expected_substrs = ['error: missing value at traceSession.processes[1].pid', "Schema"]
|
||||
expected_substrs = ['error: missing value at traceBundle.processes[1].pid', "Schema"]
|
||||
self.traceLoad(traceDescriptionFilePath=trace_description_file_path, error=True, substrs=expected_substrs)
|
||||
|
||||
|
||||
|
@ -157,6 +157,6 @@ Context:
|
|||
# no targets should be created.
|
||||
self.assertEqual(self.dbg.GetNumTargets(), 0)
|
||||
trace_description_file_path = os.path.join(src_dir, "intelpt-trace", "trace_bad3.json")
|
||||
expected_substrs = ['error: missing value at traceSession.processes[1].pid']
|
||||
expected_substrs = ['error: missing value at traceBundle.processes[1].pid']
|
||||
self.traceLoad(traceDescriptionFilePath=trace_description_file_path, error=True, substrs=expected_substrs)
|
||||
self.assertEqual(self.dbg.GetNumTargets(), 0)
|
||||
|
|
Loading…
Reference in New Issue