Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
39645 views
//===-- TraceIntelPT.h ------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H9#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H1011#include "TaskTimer.h"12#include "ThreadDecoder.h"13#include "TraceIntelPTBundleLoader.h"14#include "TraceIntelPTMultiCpuDecoder.h"15#include "lldb/Utility/FileSpec.h"16#include "lldb/lldb-types.h"17#include "llvm/Support/raw_ostream.h"18#include <optional>1920namespace lldb_private {21namespace trace_intel_pt {2223class TraceIntelPT : public Trace {24public:25/// Properties to be used with the `settings` command.26class PluginProperties : public Properties {27public:28static llvm::StringRef GetSettingName();2930PluginProperties();3132~PluginProperties() override = default;3334uint64_t GetInfiniteDecodingLoopVerificationThreshold();3536uint64_t GetExtremelyLargeDecodingThreshold();37};3839/// Return the global properties for this trace plug-in.40static PluginProperties &GetGlobalProperties();4142void Dump(Stream *s) const override;4344llvm::Expected<FileSpec> SaveToDisk(FileSpec directory,45bool compact) override;4647~TraceIntelPT() override = default;4849/// PluginInterface protocol50/// \{51llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }5253static void Initialize();5455static void Terminate();5657/// Create an instance of this class from a trace bundle.58///59/// \param[in] trace_bundle_description60/// The description of the trace bundle. See \a Trace::FindPlugin.61///62/// \param[in] bundle_dir63/// The path to the directory that contains the trace bundle.64///65/// \param[in] debugger66/// The debugger instance where new Targets will be created as part of the67/// JSON data parsing.68///69/// \return70/// A trace instance or an error in case of failures.71static llvm::Expected<lldb::TraceSP> CreateInstanceForTraceBundle(72const llvm::json::Value &trace_bundle_description,73llvm::StringRef bundle_dir, Debugger &debugger);7475static llvm::Expected<lldb::TraceSP>76CreateInstanceForLiveProcess(Process &process);7778static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; }7980static void DebuggerInitialize(Debugger &debugger);81/// \}8283lldb::CommandObjectSP84GetProcessTraceStartCommand(CommandInterpreter &interpreter) override;8586lldb::CommandObjectSP87GetThreadTraceStartCommand(CommandInterpreter &interpreter) override;8889llvm::StringRef GetSchema() override;9091llvm::Expected<lldb::TraceCursorSP> CreateNewCursor(Thread &thread) override;9293void DumpTraceInfo(Thread &thread, Stream &s, bool verbose,94bool json) override;9596llvm::Expected<std::optional<uint64_t>> GetRawTraceSize(Thread &thread);9798llvm::Error DoRefreshLiveProcessState(TraceGetStateResponse state,99llvm::StringRef json_response) override;100101bool IsTraced(lldb::tid_t tid) override;102103const char *GetStartConfigurationHelp() override;104105/// Start tracing a live process.106///107/// More information on the parameters below can be found in the108/// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.109///110/// \param[in] ipt_trace_size111/// Trace size per thread in bytes.112///113/// \param[in] total_buffer_size_limit114/// Maximum total trace size per process in bytes.115///116/// \param[in] enable_tsc117/// Whether to use enable TSC timestamps or not.118///119/// \param[in] psb_period120/// This value defines the period in which PSB packets will be generated.121///122/// \param[in] per_cpu_tracing123/// This value defines whether to have an intel pt trace buffer per thread124/// or per cpu core.125///126/// \param[in] disable_cgroup_filtering127/// Disable the cgroup filtering that is automatically applied when doing128/// per cpu tracing.129///130/// \return131/// \a llvm::Error::success if the operation was successful, or132/// \a llvm::Error otherwise.133llvm::Error Start(uint64_t ipt_trace_size, uint64_t total_buffer_size_limit,134bool enable_tsc, std::optional<uint64_t> psb_period,135bool m_per_cpu_tracing, bool disable_cgroup_filtering);136137/// \copydoc Trace::Start138llvm::Error Start(StructuredData::ObjectSP configuration =139StructuredData::ObjectSP()) override;140141/// Start tracing live threads.142///143/// More information on the parameters below can be found in the144/// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.145///146/// \param[in] tids147/// Threads to trace.148///149/// \param[in] ipt_trace_size150/// Trace size per thread or per cpu core in bytes.151///152/// \param[in] enable_tsc153/// Whether to use enable TSC timestamps or not.154///155/// \param[in] psb_period156/// This value defines the period in which PSB packets will be generated.157///158/// \return159/// \a llvm::Error::success if the operation was successful, or160/// \a llvm::Error otherwise.161llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, uint64_t ipt_trace_size,162bool enable_tsc, std::optional<uint64_t> psb_period);163164/// \copydoc Trace::Start165llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,166StructuredData::ObjectSP configuration =167StructuredData::ObjectSP()) override;168169/// See \a Trace::OnThreadBinaryDataRead().170llvm::Error OnThreadBufferRead(lldb::tid_t tid,171OnBinaryDataReadCallback callback);172173/// Get or fetch the cpu information from, for example, /proc/cpuinfo.174llvm::Expected<pt_cpu> GetCPUInfo();175176/// Get or fetch the values used to convert to and from TSCs and nanos.177std::optional<LinuxPerfZeroTscConversion> GetPerfZeroTscConversion();178179/// \return180/// The timer object for this trace.181TaskTimer &GetTimer();182183/// \return184/// The ScopedTaskTimer object for the given thread in this trace.185ScopedTaskTimer &GetThreadTimer(lldb::tid_t tid);186187/// \return188/// The global copedTaskTimer object for this trace.189ScopedTaskTimer &GetGlobalTimer();190191TraceIntelPTSP GetSharedPtr();192193enum class TraceMode { UserMode, KernelMode };194195TraceMode GetTraceMode();196197private:198friend class TraceIntelPTBundleLoader;199200llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess();201202/// Postmortem trace constructor203///204/// \param[in] bundle_description205/// The definition file for the postmortem bundle.206///207/// \param[in] traced_processes208/// The processes traced in the postmortem session.209///210/// \param[in] trace_threads211/// The threads traced in the postmortem session. They must belong to the212/// processes mentioned above.213///214/// \param[in] trace_mode215/// The tracing mode of the postmortem session.216///217/// \return218/// A TraceIntelPT shared pointer instance.219/// \{220static TraceIntelPTSP CreateInstanceForPostmortemTrace(221JSONTraceBundleDescription &bundle_description,222llvm::ArrayRef<lldb::ProcessSP> traced_processes,223llvm::ArrayRef<lldb::ThreadPostMortemTraceSP> traced_threads,224TraceMode trace_mode);225226/// This constructor is used by CreateInstanceForPostmortemTrace to get the227/// instance ready before using shared pointers, which is a limitation of C++.228TraceIntelPT(JSONTraceBundleDescription &bundle_description,229llvm::ArrayRef<lldb::ProcessSP> traced_processes,230TraceMode trace_mode);231/// \}232233/// Constructor for live processes234TraceIntelPT(Process &live_process)235: Trace(live_process), trace_mode(TraceMode::UserMode){};236237/// Decode the trace of the given thread that, i.e. recontruct the traced238/// instructions.239///240/// \param[in] thread241/// If \a thread is a \a ThreadTrace, then its internal trace file will be242/// decoded. Live threads are not currently supported.243///244/// \return245/// A \a DecodedThread shared pointer with the decoded instructions. Any246/// errors are embedded in the instruction list. An \a llvm::Error is247/// returned if the decoder couldn't be properly set up.248llvm::Expected<DecodedThreadSP> Decode(Thread &thread);249250/// \return251/// The lowest timestamp in nanoseconds in all traces if available, \a252/// std::nullopt if all the traces were empty or no trace contained no253/// timing information, or an \a llvm::Error if it was not possible to set254/// up the decoder for some trace.255llvm::Expected<std::optional<uint64_t>> FindBeginningOfTimeNanos();256257// Dump out trace info in JSON format258void DumpTraceInfoAsJson(Thread &thread, Stream &s, bool verbose);259260/// We package all the data that can change upon process stops to make sure261/// this contract is very visible.262/// This variable should only be accessed directly by constructores or live263/// process data refreshers.264struct Storage {265std::optional<TraceIntelPTMultiCpuDecoder> multicpu_decoder;266/// These decoders are used for the non-per-cpu case267llvm::DenseMap<lldb::tid_t, std::unique_ptr<ThreadDecoder>> thread_decoders;268/// Helper variable used to track long running operations for telemetry.269TaskTimer task_timer;270/// It is provided by either a trace bundle or a live process to convert TSC271/// counters to and from nanos. It might not be available on all hosts.272std::optional<LinuxPerfZeroTscConversion> tsc_conversion;273std::optional<uint64_t> beginning_of_time_nanos;274bool beginning_of_time_nanos_calculated = false;275} m_storage;276277/// It is provided by either a trace bundle or a live process' "cpuInfo"278/// binary data. We don't put it in the Storage because this variable doesn't279/// change.280std::optional<pt_cpu> m_cpu_info;281282/// Get the storage after refreshing the data in the case of a live process.283Storage &GetUpdatedStorage();284285/// The tracing mode of post mortem trace.286TraceMode trace_mode;287};288289} // namespace trace_intel_pt290} // namespace lldb_private291292#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H293294295