aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h293
1 files changed, 293 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
new file mode 100644
index 000000000000..da9cefe9ed95
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -0,0 +1,293 @@
+//===-- TraceIntelPT.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_TRACEINTELPT_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H
+
+#include "TaskTimer.h"
+#include "ThreadDecoder.h"
+#include "TraceIntelPTBundleLoader.h"
+#include "TraceIntelPTMultiCpuDecoder.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-types.h"
+#include "llvm/Support/raw_ostream.h"
+#include <optional>
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceIntelPT : public Trace {
+public:
+ /// Properties to be used with the `settings` command.
+ class PluginProperties : public Properties {
+ public:
+ static llvm::StringRef GetSettingName();
+
+ PluginProperties();
+
+ ~PluginProperties() override = default;
+
+ uint64_t GetInfiniteDecodingLoopVerificationThreshold();
+
+ uint64_t GetExtremelyLargeDecodingThreshold();
+ };
+
+ /// Return the global properties for this trace plug-in.
+ static PluginProperties &GetGlobalProperties();
+
+ void Dump(Stream *s) const override;
+
+ llvm::Expected<FileSpec> SaveToDisk(FileSpec directory,
+ bool compact) override;
+
+ ~TraceIntelPT() override = default;
+
+ /// PluginInterface protocol
+ /// \{
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ static void Initialize();
+
+ static void Terminate();
+
+ /// Create an instance of this class from a trace bundle.
+ ///
+ /// \param[in] trace_bundle_description
+ /// The description of the trace bundle. See \a Trace::FindPlugin.
+ ///
+ /// \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
+ /// JSON data parsing.
+ ///
+ /// \return
+ /// A trace instance or an error in case of failures.
+ static llvm::Expected<lldb::TraceSP> CreateInstanceForTraceBundle(
+ const llvm::json::Value &trace_bundle_description,
+ llvm::StringRef bundle_dir, Debugger &debugger);
+
+ static llvm::Expected<lldb::TraceSP>
+ CreateInstanceForLiveProcess(Process &process);
+
+ static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; }
+
+ static void DebuggerInitialize(Debugger &debugger);
+ /// \}
+
+ lldb::CommandObjectSP
+ GetProcessTraceStartCommand(CommandInterpreter &interpreter) override;
+
+ lldb::CommandObjectSP
+ GetThreadTraceStartCommand(CommandInterpreter &interpreter) override;
+
+ llvm::StringRef GetSchema() override;
+
+ llvm::Expected<lldb::TraceCursorSP> CreateNewCursor(Thread &thread) override;
+
+ void DumpTraceInfo(Thread &thread, Stream &s, bool verbose,
+ bool json) override;
+
+ llvm::Expected<std::optional<uint64_t>> GetRawTraceSize(Thread &thread);
+
+ llvm::Error DoRefreshLiveProcessState(TraceGetStateResponse state,
+ llvm::StringRef json_response) override;
+
+ bool IsTraced(lldb::tid_t tid) override;
+
+ const char *GetStartConfigurationHelp() override;
+
+ /// Start tracing a live process.
+ ///
+ /// More information on the parameters below can be found in the
+ /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.
+ ///
+ /// \param[in] ipt_trace_size
+ /// Trace size per thread in bytes.
+ ///
+ /// \param[in] total_buffer_size_limit
+ /// Maximum total trace size per process in bytes.
+ ///
+ /// \param[in] enable_tsc
+ /// Whether to use enable TSC timestamps or not.
+ ///
+ /// \param[in] psb_period
+ /// This value defines the period in which PSB packets will be generated.
+ ///
+ /// \param[in] per_cpu_tracing
+ /// This value defines whether to have an intel pt trace buffer per thread
+ /// or per cpu core.
+ ///
+ /// \param[in] disable_cgroup_filtering
+ /// Disable the cgroup filtering that is automatically applied when doing
+ /// per cpu tracing.
+ ///
+ /// \return
+ /// \a llvm::Error::success if the operation was successful, or
+ /// \a llvm::Error otherwise.
+ llvm::Error Start(uint64_t ipt_trace_size, uint64_t total_buffer_size_limit,
+ bool enable_tsc, std::optional<uint64_t> psb_period,
+ bool m_per_cpu_tracing, bool disable_cgroup_filtering);
+
+ /// \copydoc Trace::Start
+ llvm::Error Start(StructuredData::ObjectSP configuration =
+ StructuredData::ObjectSP()) override;
+
+ /// Start tracing live threads.
+ ///
+ /// More information on the parameters below can be found in the
+ /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.
+ ///
+ /// \param[in] tids
+ /// Threads to trace.
+ ///
+ /// \param[in] ipt_trace_size
+ /// Trace size per thread or per cpu core in bytes.
+ ///
+ /// \param[in] enable_tsc
+ /// Whether to use enable TSC timestamps or not.
+ ///
+ /// \param[in] psb_period
+ /// This value defines the period in which PSB packets will be generated.
+ ///
+ /// \return
+ /// \a llvm::Error::success if the operation was successful, or
+ /// \a llvm::Error otherwise.
+ llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, uint64_t ipt_trace_size,
+ bool enable_tsc, std::optional<uint64_t> psb_period);
+
+ /// \copydoc Trace::Start
+ llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,
+ StructuredData::ObjectSP configuration =
+ StructuredData::ObjectSP()) override;
+
+ /// See \a Trace::OnThreadBinaryDataRead().
+ llvm::Error OnThreadBufferRead(lldb::tid_t tid,
+ OnBinaryDataReadCallback callback);
+
+ /// Get or fetch the cpu information from, for example, /proc/cpuinfo.
+ llvm::Expected<pt_cpu> GetCPUInfo();
+
+ /// Get or fetch the values used to convert to and from TSCs and nanos.
+ std::optional<LinuxPerfZeroTscConversion> GetPerfZeroTscConversion();
+
+ /// \return
+ /// The timer object for this trace.
+ TaskTimer &GetTimer();
+
+ /// \return
+ /// The ScopedTaskTimer object for the given thread in this trace.
+ ScopedTaskTimer &GetThreadTimer(lldb::tid_t tid);
+
+ /// \return
+ /// The global copedTaskTimer object for this trace.
+ ScopedTaskTimer &GetGlobalTimer();
+
+ TraceIntelPTSP GetSharedPtr();
+
+ enum class TraceMode { UserMode, KernelMode };
+
+ TraceMode GetTraceMode();
+
+private:
+ friend class TraceIntelPTBundleLoader;
+
+ llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess();
+
+ /// Postmortem trace constructor
+ ///
+ /// \param[in] bundle_description
+ /// The definition file for the postmortem bundle.
+ ///
+ /// \param[in] traced_processes
+ /// The processes traced in the postmortem session.
+ ///
+ /// \param[in] trace_threads
+ /// The threads traced in the postmortem session. They must belong to the
+ /// processes mentioned above.
+ ///
+ /// \param[in] trace_mode
+ /// The tracing mode of the postmortem session.
+ ///
+ /// \return
+ /// A TraceIntelPT shared pointer instance.
+ /// \{
+ static TraceIntelPTSP CreateInstanceForPostmortemTrace(
+ JSONTraceBundleDescription &bundle_description,
+ llvm::ArrayRef<lldb::ProcessSP> traced_processes,
+ llvm::ArrayRef<lldb::ThreadPostMortemTraceSP> traced_threads,
+ TraceMode trace_mode);
+
+ /// This constructor is used by CreateInstanceForPostmortemTrace to get the
+ /// instance ready before using shared pointers, which is a limitation of C++.
+ TraceIntelPT(JSONTraceBundleDescription &bundle_description,
+ llvm::ArrayRef<lldb::ProcessSP> traced_processes,
+ TraceMode trace_mode);
+ /// \}
+
+ /// Constructor for live processes
+ TraceIntelPT(Process &live_process)
+ : Trace(live_process), trace_mode(TraceMode::UserMode){};
+
+ /// Decode the trace of the given thread that, i.e. recontruct the traced
+ /// instructions.
+ ///
+ /// \param[in] thread
+ /// If \a thread is a \a ThreadTrace, then its internal trace file will be
+ /// decoded. Live threads are not currently supported.
+ ///
+ /// \return
+ /// A \a DecodedThread shared pointer with the decoded instructions. Any
+ /// errors are embedded in the instruction list. An \a llvm::Error is
+ /// returned if the decoder couldn't be properly set up.
+ llvm::Expected<DecodedThreadSP> Decode(Thread &thread);
+
+ /// \return
+ /// The lowest timestamp in nanoseconds in all traces if available, \a
+ /// std::nullopt if all the traces were empty or no trace contained no
+ /// timing information, or an \a llvm::Error if it was not possible to set
+ /// up the decoder for some trace.
+ llvm::Expected<std::optional<uint64_t>> FindBeginningOfTimeNanos();
+
+ // Dump out trace info in JSON format
+ void DumpTraceInfoAsJson(Thread &thread, Stream &s, bool verbose);
+
+ /// We package all the data that can change upon process stops to make sure
+ /// this contract is very visible.
+ /// This variable should only be accessed directly by constructores or live
+ /// process data refreshers.
+ struct Storage {
+ std::optional<TraceIntelPTMultiCpuDecoder> multicpu_decoder;
+ /// These decoders are used for the non-per-cpu case
+ 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 trace bundle or a live process to convert TSC
+ /// counters to and from nanos. It might not be available on all hosts.
+ std::optional<LinuxPerfZeroTscConversion> tsc_conversion;
+ std::optional<uint64_t> beginning_of_time_nanos;
+ bool beginning_of_time_nanos_calculated = false;
+ } m_storage;
+
+ /// 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.
+ std::optional<pt_cpu> m_cpu_info;
+
+ /// Get the storage after refreshing the data in the case of a live process.
+ Storage &GetUpdatedStorage();
+
+ /// The tracing mode of post mortem trace.
+ TraceMode trace_mode;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H